2013-09-19 07:35:34 +00:00
|
|
|
#ifndef PICTURE_H_
|
|
|
|
#define PICTURE_H_
|
2014-01-24 10:37:15 +00:00
|
|
|
/*****************************************************************************
|
|
|
|
* This file is part of Kvazaar HEVC encoder.
|
2014-02-21 13:00:20 +00:00
|
|
|
*
|
|
|
|
* Copyright (C) 2013-2014 Tampere University of Technology and others (see
|
2014-01-24 10:37:15 +00:00
|
|
|
* COPYING file).
|
|
|
|
*
|
|
|
|
* Kvazaar is free software: you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License version 2 as published
|
|
|
|
* by the Free Software Foundation.
|
|
|
|
*
|
|
|
|
* Kvazaar 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 Kvazaar. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
/*
|
2013-09-18 14:29:30 +00:00
|
|
|
* \file
|
|
|
|
* \brief Coding Unit (CU) and picture data related functions.
|
2012-06-05 11:01:47 +00:00
|
|
|
*/
|
|
|
|
|
2013-09-18 09:16:03 +00:00
|
|
|
#include "global.h"
|
|
|
|
|
2013-11-04 17:27:47 +00:00
|
|
|
//#include "sao.h"
|
|
|
|
struct sao_info_struct;
|
|
|
|
|
2012-06-05 11:01:47 +00:00
|
|
|
|
2013-09-20 08:07:31 +00:00
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
// CONSTANTS
|
2013-09-16 14:34:20 +00:00
|
|
|
|
2014-05-12 06:49:28 +00:00
|
|
|
typedef enum { CU_NOTSET = 0, CU_PCM, CU_SKIP, CU_SPLIT, CU_INTRA, CU_INTER } cu_type_t;
|
2013-09-20 08:07:31 +00:00
|
|
|
enum { SLICE_B = 0, SLICE_P = 1, SLICE_I = 2 };
|
|
|
|
enum { REF_PIC_LIST_0 = 0, REF_PIC_LIST_1 = 1, REF_PIC_LIST_X = 100 };
|
2013-11-12 10:44:58 +00:00
|
|
|
typedef enum { COLOR_Y = 0, COLOR_U, COLOR_V, NUM_COLORS } color_index;
|
2013-03-12 15:06:21 +00:00
|
|
|
|
2012-06-05 11:01:47 +00:00
|
|
|
|
2013-09-20 08:07:31 +00:00
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
// TYPES
|
2012-06-11 12:26:32 +00:00
|
|
|
|
2013-11-12 10:44:58 +00:00
|
|
|
typedef struct {
|
|
|
|
int x;
|
|
|
|
int y;
|
|
|
|
} vector2d;
|
|
|
|
|
2013-09-20 08:07:31 +00:00
|
|
|
/**
|
|
|
|
* \brief Struct for CU intra info
|
|
|
|
*/
|
2012-06-11 12:26:32 +00:00
|
|
|
typedef struct
|
|
|
|
{
|
2014-03-07 13:05:39 +00:00
|
|
|
uint32_t cost;
|
|
|
|
uint32_t bitcost;
|
2013-04-18 11:04:15 +00:00
|
|
|
int8_t mode;
|
2013-10-18 08:39:13 +00:00
|
|
|
int8_t mode_chroma;
|
2014-04-02 07:54:03 +00:00
|
|
|
int8_t tr_skip; //!< \brief transform skip flag
|
2013-09-20 09:49:44 +00:00
|
|
|
} cu_info_intra;
|
2012-06-11 12:26:32 +00:00
|
|
|
|
2013-09-20 08:07:31 +00:00
|
|
|
/**
|
|
|
|
* \brief Struct for CU inter info
|
|
|
|
*/
|
2013-04-10 13:55:31 +00:00
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
uint32_t cost;
|
2014-03-07 13:05:39 +00:00
|
|
|
uint32_t bitcost;
|
2013-04-10 13:55:31 +00:00
|
|
|
int16_t mv[2];
|
2013-10-22 13:53:18 +00:00
|
|
|
int16_t mvd[2];
|
2014-02-07 22:32:10 +00:00
|
|
|
uint8_t mv_cand; // \brief selected MV candidate
|
2013-09-16 11:42:05 +00:00
|
|
|
uint8_t mv_ref; // \brief Index of the encoder_control.ref array.
|
|
|
|
uint8_t mv_dir; // \brief Probably describes if mv_ref is forward, backward or both. Might not be needed?
|
2014-03-07 13:05:39 +00:00
|
|
|
int8_t mode;
|
2013-09-20 09:49:44 +00:00
|
|
|
} cu_info_inter;
|
2013-04-10 13:55:31 +00:00
|
|
|
|
2014-05-06 11:43:12 +00:00
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
uint8_t y;
|
|
|
|
uint8_t u;
|
|
|
|
uint8_t v;
|
|
|
|
} cu_cbf_t;
|
|
|
|
|
2013-09-20 08:07:31 +00:00
|
|
|
/**
|
|
|
|
* \brief Struct for CU info
|
|
|
|
*/
|
2012-06-11 12:26:32 +00:00
|
|
|
typedef struct
|
2014-02-21 13:00:20 +00:00
|
|
|
{
|
2013-10-17 12:14:22 +00:00
|
|
|
int8_t type; //!< \brief block type, CU_INTER / CU_INTRA
|
|
|
|
int8_t depth; //!< \brief depth / size of this block
|
|
|
|
int8_t part_size; //!< \brief Currently only 2Nx2N, TODO: AMP/SMP/NxN parts
|
|
|
|
int8_t tr_depth; //!< \brief transform depth
|
|
|
|
int8_t coded; //!< \brief flag to indicate this block is coded and reconstructed
|
2013-10-18 08:39:13 +00:00
|
|
|
int8_t skipped; //!< \brief flag to indicate this block is skipped
|
|
|
|
int8_t merged; //!< \brief flag to indicate this block is merged
|
2013-10-23 12:14:26 +00:00
|
|
|
int8_t merge_idx; //!< \brief merge index
|
2013-10-18 08:39:13 +00:00
|
|
|
|
2014-05-06 11:43:12 +00:00
|
|
|
cu_cbf_t cbf;
|
2014-01-02 13:02:17 +00:00
|
|
|
cu_info_intra intra[4];
|
2013-09-20 09:49:44 +00:00
|
|
|
cu_info_inter inter;
|
|
|
|
} cu_info;
|
2012-06-11 12:26:32 +00:00
|
|
|
|
2013-09-20 08:07:31 +00:00
|
|
|
/**
|
|
|
|
* \brief Struct which contains all picture data
|
|
|
|
*/
|
2013-11-12 10:44:58 +00:00
|
|
|
typedef struct picture_struct
|
2012-06-05 11:01:47 +00:00
|
|
|
{
|
2013-10-17 12:14:22 +00:00
|
|
|
pixel* y_data; //!< \brief Pointer to luma pixel array.
|
|
|
|
pixel* u_data; //!< \brief Pointer to chroma U pixel array.
|
|
|
|
pixel* v_data; //!< \brief Pointer to chroma V pixel array.
|
2013-11-13 12:42:41 +00:00
|
|
|
pixel *data[NUM_COLORS]; // \brief Alternate access method to same data.
|
2013-09-20 08:07:31 +00:00
|
|
|
|
2013-10-17 12:14:22 +00:00
|
|
|
pixel* y_recdata; //!< \brief Pointer to reconstructed Y-data.
|
|
|
|
pixel* u_recdata; //!< \brief Pointer to reconstructed U-data.
|
|
|
|
pixel* v_recdata; //!< \brief Pointer to reconstructed V-data.
|
2013-11-13 12:42:41 +00:00
|
|
|
pixel *recdata[NUM_COLORS]; // \brief Alternate access method to same data.
|
2013-09-20 08:07:31 +00:00
|
|
|
|
2013-10-18 08:39:13 +00:00
|
|
|
coefficient* coeff_y; //!< \brief coefficient pointer Y
|
|
|
|
coefficient* coeff_u; //!< \brief coefficient pointer U
|
|
|
|
coefficient* coeff_v; //!< \brief coefficient pointer V
|
2013-10-15 14:56:50 +00:00
|
|
|
|
2013-10-17 12:14:22 +00:00
|
|
|
int32_t width; //!< \brief Luma pixel array width.
|
|
|
|
int32_t height; //!< \brief Luma pixel array height.
|
|
|
|
int32_t height_in_lcu; //!< \brief Picture width in number of LCU's.
|
|
|
|
int32_t width_in_lcu; //!< \brief Picture height in number of LCU's.
|
|
|
|
uint8_t referenced; //!< \brief Whether this picture is referenced.
|
2014-05-05 05:54:39 +00:00
|
|
|
int32_t refcount; //!< \brief Number of references in reflist to the picture
|
2014-04-28 07:18:22 +00:00
|
|
|
cu_info* cu_array; //!< \brief Info for each CU at each depth.
|
2013-11-04 17:27:47 +00:00
|
|
|
struct sao_info_struct *sao_luma; //!< \brief Array of sao parameters for every LCU.
|
|
|
|
struct sao_info_struct *sao_chroma; //!< \brief Array of sao parameters for every LCU.
|
2014-02-07 22:32:10 +00:00
|
|
|
int32_t poc; //!< \brief Picture order count
|
2012-06-05 11:01:47 +00:00
|
|
|
} picture;
|
|
|
|
|
2013-09-20 08:07:31 +00:00
|
|
|
/**
|
|
|
|
* \brief Struct which contains array of picture structs
|
|
|
|
*/
|
2012-06-05 11:01:47 +00:00
|
|
|
typedef struct
|
|
|
|
{
|
2013-10-17 12:14:22 +00:00
|
|
|
picture** pics; //!< \brief Pointer to array of picture pointers.
|
2014-04-04 08:08:34 +00:00
|
|
|
uint32_t size; //!< \brief Array size.
|
|
|
|
uint32_t used_size;
|
2012-06-05 11:01:47 +00:00
|
|
|
} picture_list;
|
|
|
|
|
|
|
|
|
2014-02-26 12:57:57 +00:00
|
|
|
|
2014-02-26 14:05:38 +00:00
|
|
|
#define SUB_SCU_BIT_MASK (64 - 1)
|
2014-02-26 12:57:57 +00:00
|
|
|
#define SUB_SCU(xy) (xy & SUB_SCU_BIT_MASK)
|
|
|
|
#define LCU_CU_WIDTH 8
|
|
|
|
#define LCU_T_CU_WIDTH 9
|
|
|
|
#define LCU_CU_OFFSET 10
|
|
|
|
|
|
|
|
// Width from top left of the LCU, so +1 for ref buffer size.
|
|
|
|
#define LCU_REF_PX_WIDTH (LCU_WIDTH + LCU_WIDTH / 2)
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Top and left intra reference pixels for LCU.
|
|
|
|
* - Intra needs maximum of 32 to the right and down from LCU border.
|
|
|
|
* - First pixel is the top-left pixel.
|
|
|
|
*/
|
|
|
|
typedef struct {
|
|
|
|
pixel y[LCU_REF_PX_WIDTH + 1];
|
|
|
|
pixel u[LCU_REF_PX_WIDTH / 2 + 1];
|
|
|
|
pixel v[LCU_REF_PX_WIDTH / 2 + 1];
|
|
|
|
} lcu_ref_px_t;
|
|
|
|
|
|
|
|
typedef struct {
|
2014-02-27 09:05:21 +00:00
|
|
|
coefficient y[LCU_LUMA_SIZE];
|
|
|
|
coefficient u[LCU_CHROMA_SIZE];
|
|
|
|
coefficient v[LCU_CHROMA_SIZE];
|
2014-02-26 12:57:57 +00:00
|
|
|
} lcu_coeff_t;
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
pixel y[LCU_LUMA_SIZE];
|
|
|
|
pixel u[LCU_CHROMA_SIZE];
|
|
|
|
pixel v[LCU_CHROMA_SIZE];
|
|
|
|
} lcu_yuv_t;
|
|
|
|
|
2014-03-18 09:26:42 +00:00
|
|
|
typedef struct {
|
|
|
|
int size;
|
|
|
|
pixel *y;
|
|
|
|
pixel *u;
|
|
|
|
pixel *v;
|
|
|
|
} yuv_t;
|
|
|
|
|
2014-02-26 12:57:57 +00:00
|
|
|
typedef struct {
|
|
|
|
lcu_ref_px_t top_ref; //!< Reference pixels from adjacent LCUs.
|
|
|
|
lcu_ref_px_t left_ref; //!< Reference pixels from adjacent LCUs.
|
|
|
|
lcu_yuv_t ref; //!< LCU reference pixels
|
|
|
|
lcu_yuv_t rec; //!< LCU reconstructed pixels
|
2014-02-27 09:56:16 +00:00
|
|
|
/**
|
|
|
|
* We get the coefficients as a byproduct of doing reconstruction during the
|
|
|
|
* search. It might be more efficient to recalculate the final coefficients
|
|
|
|
* once we know the final modes rather than copying them.
|
|
|
|
*/
|
2014-02-26 12:57:57 +00:00
|
|
|
lcu_coeff_t coeff; //!< LCU coefficients
|
|
|
|
|
|
|
|
/**
|
|
|
|
* A 9x9 CU array for the LCU, +1 CU.
|
|
|
|
* - Top reference CUs on row 0.
|
|
|
|
* - Left reference CUs on column 0.
|
|
|
|
* - All of LCUs CUs on 1:9, 1:9.
|
|
|
|
* - Top right reference CU on the last slot.
|
|
|
|
*/
|
|
|
|
cu_info cu[9*9+1];
|
|
|
|
} lcu_t;
|
|
|
|
|
2013-09-20 08:07:31 +00:00
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
// FUNCTIONS
|
2012-06-05 11:01:47 +00:00
|
|
|
|
2014-05-06 11:43:12 +00:00
|
|
|
/**
|
|
|
|
* Check if CBF in a given level >= depth is true.
|
|
|
|
*/
|
|
|
|
static INLINE int cbf_is_set(uint8_t cbf_flags, int depth)
|
|
|
|
{
|
|
|
|
// Transform data for 4x4 blocks is stored at depths 4-8 for luma, so masks
|
|
|
|
// for those levels don't include the other ones.
|
|
|
|
static const uint8_t masks[8] = { 0xff, 0x7f, 0x3f, 0x1f, 0x8, 0x4, 0x2, 0x1 };
|
|
|
|
|
|
|
|
return (cbf_flags & masks[depth]) != 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Set CBF in a level to true.
|
|
|
|
*/
|
|
|
|
static INLINE void cbf_set(uint8_t *cbf_flags, int depth)
|
|
|
|
{
|
|
|
|
// Return value of the bit corresponding to the level.
|
|
|
|
*cbf_flags |= 1 << (7 - depth);
|
|
|
|
}
|
|
|
|
|
2014-05-06 12:22:31 +00:00
|
|
|
/**
|
|
|
|
* Set CBF in a levels <= depth to false.
|
|
|
|
*/
|
|
|
|
static INLINE void cbf_clear(uint8_t *cbf_flags, int depth)
|
|
|
|
{
|
|
|
|
static const uint8_t masks[8] = { 0xff, 0x7f, 0x3f, 0x1f, 0x8, 0x4, 0x2, 0x1 };
|
|
|
|
|
|
|
|
*cbf_flags &= ~masks[depth];
|
|
|
|
}
|
|
|
|
|
2014-05-02 09:45:27 +00:00
|
|
|
yuv_t * yuv_t_alloc(int luma_size);
|
|
|
|
void yuv_t_free(yuv_t * yuv);
|
2014-03-18 09:26:42 +00:00
|
|
|
|
2014-05-02 08:58:28 +00:00
|
|
|
picture * picture_alloc(int32_t width, int32_t height,
|
2013-09-20 08:07:31 +00:00
|
|
|
int32_t width_in_lcu, int32_t height_in_lcu);
|
2014-05-02 08:58:28 +00:00
|
|
|
int picture_free(picture *pic);
|
2014-03-05 15:22:36 +00:00
|
|
|
|
2013-10-25 14:14:20 +00:00
|
|
|
void picture_blit_pixels(const pixel* orig, pixel *dst,
|
|
|
|
unsigned width, unsigned height,
|
|
|
|
unsigned orig_stride, unsigned dst_stride);
|
2014-02-27 09:56:16 +00:00
|
|
|
void picture_blit_coeffs(const coefficient *orig, coefficient *dst,
|
|
|
|
unsigned width, unsigned height,
|
|
|
|
unsigned orig_stride, unsigned dst_stride);
|
2012-06-05 11:01:47 +00:00
|
|
|
|
2013-09-20 08:07:31 +00:00
|
|
|
picture_list * picture_list_init(int size);
|
2014-02-10 14:48:50 +00:00
|
|
|
int picture_list_resize(picture_list *list, unsigned size);
|
2013-09-20 08:07:31 +00:00
|
|
|
int picture_list_destroy(picture_list *list);
|
|
|
|
int picture_list_add(picture_list *list, picture *pic);
|
2014-05-05 05:54:39 +00:00
|
|
|
int picture_list_rem(picture_list *list, unsigned n);
|
2013-09-20 08:07:31 +00:00
|
|
|
|
2013-10-18 11:23:21 +00:00
|
|
|
typedef unsigned (*cost_16bit_nxn_func)(pixel *block1, pixel *block2);
|
2013-10-16 12:08:53 +00:00
|
|
|
|
|
|
|
|
|
|
|
cost_16bit_nxn_func get_satd_16bit_nxn_func(unsigned n);
|
|
|
|
cost_16bit_nxn_func get_sad_16bit_nxn_func(unsigned n);
|
|
|
|
|
2013-10-18 11:23:21 +00:00
|
|
|
unsigned satd_16bit_nxn(pixel *block1, pixel *block2, unsigned n);
|
|
|
|
unsigned sad_16bit_nxn(pixel *block1, pixel *block2, unsigned n);
|
2013-10-10 15:51:10 +00:00
|
|
|
|
2014-02-21 13:00:20 +00:00
|
|
|
unsigned calc_sad(const picture *pic, const picture *ref,
|
|
|
|
int pic_x, int pic_y, int ref_x, int ref_y,
|
2013-10-11 12:31:55 +00:00
|
|
|
int block_width, int block_height);
|
2013-09-12 14:15:14 +00:00
|
|
|
|
2014-05-13 16:45:50 +00:00
|
|
|
unsigned calc_ssd(const pixel *const ref, const pixel *const rec,
|
|
|
|
const int ref_stride, const int rec_stride,
|
|
|
|
const int width);
|
|
|
|
|
2013-10-14 14:27:25 +00:00
|
|
|
double image_psnr(pixel *frame1, pixel *frame2, int32_t x, int32_t y);
|
2012-06-05 11:01:47 +00:00
|
|
|
|
2012-06-06 11:09:28 +00:00
|
|
|
|
2013-09-20 08:07:31 +00:00
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
// MACROS
|
2013-08-02 13:35:30 +00:00
|
|
|
|
2013-09-20 08:07:31 +00:00
|
|
|
#define GET_SPLITDATA(CU,curDepth) ((CU)->depth > curDepth)
|
|
|
|
#define SET_SPLITDATA(CU,flag) { (CU)->split=(flag); }
|
2012-06-06 11:09:28 +00:00
|
|
|
|
2012-06-05 11:01:47 +00:00
|
|
|
|
2013-09-20 08:07:31 +00:00
|
|
|
#endif
|