cu_array data structure

This commit is contained in:
Laurent Fasnacht 2014-06-16 08:17:22 +02:00
parent 3be3fa8d6e
commit f4187dd10c
8 changed files with 67 additions and 31 deletions

View file

@ -25,6 +25,7 @@
#include <stdlib.h>
#include "cu.h"
#include "threads.h"
void coefficients_blit(const coefficient * const orig, coefficient * const dst,
@ -52,3 +53,25 @@ unsigned coefficients_calc_abs(const coefficient *const buf, const int buf_strid
return sum;
}
cu_array * cu_array_alloc(const int width_in_scu, const int height_in_scu) {
unsigned cu_array_size = height_in_scu * width_in_scu;
cu_array *cua;
cua = MALLOC(cu_array, 1);
cua->data = (cu_info*)malloc(sizeof(cu_info) * cu_array_size);
cua->refcount = 1;
memset(cua->data, 0, sizeof(cu_info) * cu_array_size);
return cua;
}
int cu_array_free(cu_array * const cua)
{
int32_t new_refcount = ATOMIC_DEC(&(cua->refcount));
//Still we have some references, do nothing
if (new_refcount > 0) return 1;
FREE_POINTER(cua->data);
free(cua);
return 1;
}

View file

@ -111,6 +111,15 @@ typedef struct
(cu).inter.cost, (cu).inter.bitcost, (cu).inter.mv[0], (cu).inter.mv[1], (cu).inter.mvd[0], (cu).inter.mvd[1], \
(cu).inter.mv_cand, (cu).inter.mv_ref, (cu).inter.mv_dir, (cu).inter.mode)
typedef struct {
cu_info *data; //!< \brief cu_info data
int32_t refcount; //!< \brief number of references in reflists to this cu_array
} cu_array;
cu_array * cu_array_alloc(int width_in_scu, int height_in_scu);
int cu_array_free(cu_array *cua);
#define SUB_SCU_BIT_MASK (64 - 1)
#define SUB_SCU(xy) (xy & SUB_SCU_BIT_MASK)
#define LCU_CU_WIDTH 8

View file

@ -791,6 +791,13 @@ void encoder_next_frame(encoder_state *encoder_state) {
encoder_state->tile->frame->rec = image_alloc(encoder_state->tile->frame->width, encoder_state->tile->frame->height, encoder_state->global->poc);
videoframe_set_poc(encoder_state->tile->frame, encoder_state->global->poc);
image_list_copy_contents(encoder_state->global->ref, encoder_state->previous_encoder_state->global->ref);
image_list_add(encoder_state->global->ref, encoder_state->previous_encoder_state->tile->frame->rec, encoder_state->previous_encoder_state->tile->frame->cu_array);
// Remove the ref pics in excess
while (encoder_state->global->ref->used_size > (uint32_t)encoder->cfg->ref_frames) {
image_list_rem(encoder_state->global->ref, encoder_state->global->ref->used_size-1);
}
return; //FIXME reference frames
}

View file

@ -43,7 +43,7 @@ image_list * image_list_alloc(int size)
list->size = size;
if (size > 0) {
list->images = (image**)malloc(sizeof(image*) * size);
list->cu_arrays = (cu_info**)malloc(sizeof(cu_info*) * size);
list->cu_arrays = (cu_array**)malloc(sizeof(cu_array*) * size);
}
list->used_size = 0;
@ -61,7 +61,7 @@ int image_list_resize(image_list *list, unsigned size)
{
unsigned int i;
image** old_images = NULL;
cu_info** old_cu_arrays = NULL;
cu_array** old_cu_arrays = NULL;
//FIXME This could be done in a simple way using realloc...
@ -78,7 +78,7 @@ int image_list_resize(image_list *list, unsigned size)
// allocate space for the new list
list->images = (image**)malloc(sizeof(image*)*size);
list->cu_arrays = (cu_info**)malloc(sizeof(cu_info*)*size);
list->cu_arrays = (cu_array**)malloc(sizeof(cu_array*)*size);
// Copy everything from the old list to the new if needed.
if (old_images != NULL) {
@ -106,7 +106,7 @@ int image_list_destroy(image_list *list)
for (i = 0; i < list->used_size; ++i) {
image_free(list->images[i]);
list->images[i] = NULL;
free(list->cu_arrays[i]);
cu_array_free(list->cu_arrays[i]);
list->cu_arrays[i] = NULL;
}
}
@ -125,7 +125,7 @@ int image_list_destroy(image_list *list)
* \param picture_list list to use
* \return 1 on success
*/
int image_list_add(image_list *list, image* im, cu_info* cu_array)
int image_list_add(image_list *list, image* im, cu_array* cua)
{
int i = 0;
if (ATOMIC_INC(&(im->refcount)) == 1) {
@ -134,6 +134,12 @@ int image_list_add(image_list *list, image* im, cu_info* cu_array)
return 0;
}
if (ATOMIC_INC(&(cua->refcount)) == 1) {
fprintf(stderr, "Tried to add an unreferenced cu_array. This is a bug!\n");
assert(0); //Stop for debugging
return 0;
}
if (list->size == list->used_size) {
if (!image_list_resize(list, list->size*2)) return 0;
}
@ -144,20 +150,8 @@ int image_list_add(image_list *list, image* im, cu_info* cu_array)
}
list->images[0] = im;
//We need (only here, for malloc/memcpy) to compute the size of the image in SCU
{
//FIXME FIXME FIXME Do like images, use a pointer instead of copying
unsigned int width_in_lcu, height_in_lcu, width_in_scu, height_in_scu;
width_in_lcu = im->width / LCU_WIDTH;
if (width_in_lcu * LCU_WIDTH < im->width) width_in_lcu++;
height_in_lcu = im->height / LCU_WIDTH;
if (height_in_lcu * LCU_WIDTH < im->height) height_in_lcu++;
height_in_scu = height_in_lcu << MAX_DEPTH;
width_in_scu = width_in_lcu << MAX_DEPTH;
list->cu_arrays[0] = cua;
list->cu_arrays[0] = (cu_info*)malloc(sizeof(cu_info) * width_in_scu * height_in_scu);
memcpy(list->cu_arrays[0], cu_array, sizeof(cu_info) * width_in_scu * height_in_scu);
}
list->used_size++;
return 1;
}
@ -181,7 +175,12 @@ int image_list_rem(image_list * const list, const unsigned n)
assert(0); //Stop here
return 0;
}
free(list->cu_arrays[n]);
if (!cu_array_free(list->cu_arrays[n])) {
fprintf(stderr, "Could not free cu_array!\n");
assert(0); //Stop here
return 0;
}
// The last item is easy to remove
if (n == list->used_size - 1) {

View file

@ -32,8 +32,8 @@
*/
typedef struct
{
struct image** images; //!< \brief Pointer to array of picture pointers.
cu_info** cu_arrays;
struct image* *images; //!< \brief Pointer to array of picture pointers.
cu_array* *cu_arrays;
uint32_t size; //!< \brief Array size.
uint32_t used_size;
} image_list;
@ -41,7 +41,7 @@ typedef struct
image_list * image_list_alloc(int size);
int image_list_resize(image_list *list, unsigned size);
int image_list_destroy(image_list *list);
int image_list_add(image_list *list, image *im, cu_info* cu_array);
int image_list_add(image_list *list, image *im, cu_array* cua);
int image_list_rem(image_list *list, unsigned n);
enum { REF_PIC_LIST_0 = 0, REF_PIC_LIST_1 = 1, REF_PIC_LIST_X = 100 };

View file

@ -398,7 +398,7 @@ static int search_cu_inter(const encoder_state * const encoder_state, int x, int
for (ref_idx = 0; ref_idx < encoder_state->global->ref->used_size; ref_idx++) {
image *ref_image = encoder_state->global->ref->images[ref_idx];
const cu_info *ref_cu = &encoder_state->global->ref->cu_arrays[ref_idx][x_cu + y_cu * (frame->width_in_lcu << MAX_DEPTH)];
const cu_info *ref_cu = &encoder_state->global->ref->cu_arrays[ref_idx]->data[x_cu + y_cu * (frame->width_in_lcu << MAX_DEPTH)];
uint32_t temp_bitcost = 0;
uint32_t temp_cost = 0;
vector2d orig, mv, mvd;

View file

@ -56,9 +56,7 @@ videoframe *videoframe_alloc(const int32_t width, const int32_t height, const in
// Allocate height_in_scu x width_in_scu x sizeof(CU_info)
unsigned height_in_scu = frame->height_in_lcu << MAX_DEPTH;
unsigned width_in_scu = frame->width_in_lcu << MAX_DEPTH;
unsigned cu_array_size = height_in_scu * width_in_scu;
frame->cu_array = (cu_info*)malloc(sizeof(cu_info) * cu_array_size);
memset(frame->cu_array, 0, sizeof(cu_info) * cu_array_size);
frame->cu_array = cu_array_alloc(width_in_scu, height_in_scu);
}
frame->coeff_y = NULL; frame->coeff_u = NULL; frame->coeff_v = NULL;
@ -103,14 +101,14 @@ const cu_info* videoframe_get_cu_const(const videoframe * const frame, unsigned
assert(x_in_scu < (frame->width_in_lcu << MAX_DEPTH));
assert(y_in_scu < (frame->height_in_lcu << MAX_DEPTH));
return &frame->cu_array[x_in_scu + y_in_scu * (frame->width_in_lcu << MAX_DEPTH)];
return &frame->cu_array->data[x_in_scu + y_in_scu * (frame->width_in_lcu << MAX_DEPTH)];
}
cu_info* videoframe_get_cu(videoframe * const frame, const unsigned int x_in_scu, const unsigned int y_in_scu) {
assert(x_in_scu < (frame->width_in_lcu << MAX_DEPTH));
assert(y_in_scu < (frame->height_in_lcu << MAX_DEPTH));
return &frame->cu_array[x_in_scu + y_in_scu * (frame->width_in_lcu << MAX_DEPTH)];
return &frame->cu_array->data[x_in_scu + y_in_scu * (frame->width_in_lcu << MAX_DEPTH)];
}
#define PSNRMAX (255.0 * 255.0)

View file

@ -47,7 +47,7 @@ typedef struct videoframe
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.
cu_info* cu_array; //!< \brief Info for each CU at each depth.
cu_array* cu_array; //!< \brief Info for each CU at each depth.
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.
int32_t poc; //!< \brief Picture order count