mirror of
https://github.com/ultravideo/uvg266.git
synced 2024-11-28 03:34:06 +00:00
Reference count for picture
This commit is contained in:
parent
323054d5e2
commit
7f6f4fe9c1
|
@ -442,7 +442,7 @@ static void encoder_clear_refs(encoder_state *encoder_state) {
|
||||||
}
|
}
|
||||||
|
|
||||||
while (encoder_state->ref->used_size) {
|
while (encoder_state->ref->used_size) {
|
||||||
picture_list_rem(encoder_state->ref, encoder_state->ref->used_size - 1, 1);
|
picture_list_rem(encoder_state->ref, encoder_state->ref->used_size - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
encoder_state->poc = 0;
|
encoder_state->poc = 0;
|
||||||
|
@ -1375,21 +1375,25 @@ static void encode_VUI(encoder_state * const encoder_state)
|
||||||
|
|
||||||
void encoder_next_frame(encoder_state *encoder_state) {
|
void encoder_next_frame(encoder_state *encoder_state) {
|
||||||
const encoder_control * const encoder = encoder_state->encoder_control;
|
const encoder_control * const encoder = encoder_state->encoder_control;
|
||||||
|
picture *old_pic;
|
||||||
|
|
||||||
// Remove the ref pic (if present)
|
// Remove the ref pic (if present)
|
||||||
if (encoder_state->ref->used_size == (uint32_t)encoder->cfg->ref_frames) {
|
if (encoder_state->ref->used_size == (uint32_t)encoder->cfg->ref_frames) {
|
||||||
picture_list_rem(encoder_state->ref, encoder_state->ref->used_size-1, 1);
|
picture_list_rem(encoder_state->ref, encoder_state->ref->used_size-1);
|
||||||
}
|
}
|
||||||
// Add current picture as reference
|
// Add current picture as reference
|
||||||
picture_list_add(encoder_state->ref, encoder_state->cur_pic);
|
picture_list_add(encoder_state->ref, encoder_state->cur_pic);
|
||||||
// Allocate new memory to current picture
|
// Allocate new memory to current picture
|
||||||
|
old_pic = encoder_state->cur_pic;
|
||||||
// TODO: reuse memory from old reference
|
// TODO: reuse memory from old reference
|
||||||
encoder_state->cur_pic = picture_alloc(encoder_state->cur_pic->width, encoder_state->cur_pic->height, encoder_state->cur_pic->width_in_lcu, encoder_state->cur_pic->height_in_lcu);
|
encoder_state->cur_pic = picture_alloc(encoder_state->cur_pic->width, encoder_state->cur_pic->height, encoder_state->cur_pic->width_in_lcu, encoder_state->cur_pic->height_in_lcu);
|
||||||
|
|
||||||
// Copy pointer from the last cur_pic because we don't want to reallocate it
|
// Copy pointer from the last cur_pic because we don't want to reallocate it
|
||||||
MOVE_POINTER(encoder_state->cur_pic->coeff_y,encoder_state->ref->pics[0]->coeff_y);
|
MOVE_POINTER(encoder_state->cur_pic->coeff_y,old_pic->coeff_y);
|
||||||
MOVE_POINTER(encoder_state->cur_pic->coeff_u,encoder_state->ref->pics[0]->coeff_u);
|
MOVE_POINTER(encoder_state->cur_pic->coeff_u,old_pic->coeff_u);
|
||||||
MOVE_POINTER(encoder_state->cur_pic->coeff_v,encoder_state->ref->pics[0]->coeff_v);
|
MOVE_POINTER(encoder_state->cur_pic->coeff_v,old_pic->coeff_v);
|
||||||
|
|
||||||
|
picture_free(old_pic);
|
||||||
|
|
||||||
encoder_state->frame++;
|
encoder_state->frame++;
|
||||||
encoder_state->poc++;
|
encoder_state->poc++;
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
* \file
|
* \file
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "threads.h"
|
||||||
#include "picture.h"
|
#include "picture.h"
|
||||||
#include "strategyselector.h"
|
#include "strategyselector.h"
|
||||||
|
|
||||||
|
@ -192,6 +193,11 @@ int picture_list_destroy(picture_list *list)
|
||||||
*/
|
*/
|
||||||
int picture_list_add(picture_list *list,picture* pic)
|
int picture_list_add(picture_list *list,picture* pic)
|
||||||
{
|
{
|
||||||
|
if (ATOMIC_INC(&(pic->refcount)) == 1) {
|
||||||
|
fprintf(stderr, "Tried to add an unreferenced picture. This is a bug!\n");
|
||||||
|
assert(0); //Stop for debugging
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
int i = 0;
|
int i = 0;
|
||||||
if (list->size == list->used_size) {
|
if (list->size == list->used_size) {
|
||||||
if (!picture_list_resize(list, list->size*2)) return 0;
|
if (!picture_list_resize(list, list->size*2)) return 0;
|
||||||
|
@ -212,7 +218,7 @@ int picture_list_add(picture_list *list,picture* pic)
|
||||||
* \param picture_list list to use
|
* \param picture_list list to use
|
||||||
* \return 1 on success
|
* \return 1 on success
|
||||||
*/
|
*/
|
||||||
int picture_list_rem(picture_list *list, unsigned n, int8_t destroy)
|
int picture_list_rem(picture_list * const list, const unsigned n)
|
||||||
{
|
{
|
||||||
// Must be within list boundaries
|
// Must be within list boundaries
|
||||||
if (n >= list->used_size)
|
if (n >= list->used_size)
|
||||||
|
@ -220,9 +226,10 @@ int picture_list_rem(picture_list *list, unsigned n, int8_t destroy)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (destroy) {
|
if (!picture_free(list->pics[n])) {
|
||||||
picture_free(list->pics[n]);
|
fprintf(stderr, "Could not free picture!\n");
|
||||||
list->pics[n] = NULL;
|
assert(0); //Stop here
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The last item is easy to remove
|
// The last item is easy to remove
|
||||||
|
@ -230,9 +237,10 @@ int picture_list_rem(picture_list *list, unsigned n, int8_t destroy)
|
||||||
list->pics[n] = NULL;
|
list->pics[n] = NULL;
|
||||||
list->used_size--;
|
list->used_size--;
|
||||||
} else {
|
} else {
|
||||||
|
int i = n;
|
||||||
// Shift all following pics one backward in the list
|
// Shift all following pics one backward in the list
|
||||||
for (; n < list->used_size - 1; ++n) {
|
for (i = n; i < list->used_size - 1; ++i) {
|
||||||
list->pics[n] = list->pics[n + 1];
|
list->pics[i] = list->pics[i + 1];
|
||||||
}
|
}
|
||||||
list->pics[list->used_size - 1] = NULL;
|
list->pics[list->used_size - 1] = NULL;
|
||||||
list->used_size--;
|
list->used_size--;
|
||||||
|
@ -262,6 +270,7 @@ picture *picture_alloc(const int32_t width, const int32_t height,
|
||||||
pic->width_in_lcu = width_in_lcu;
|
pic->width_in_lcu = width_in_lcu;
|
||||||
pic->height_in_lcu = height_in_lcu;
|
pic->height_in_lcu = height_in_lcu;
|
||||||
pic->referenced = 0;
|
pic->referenced = 0;
|
||||||
|
pic->refcount = 1; //We give a reference to caller
|
||||||
// Allocate buffers
|
// Allocate buffers
|
||||||
pic->y_data = MALLOC(pixel, luma_size);
|
pic->y_data = MALLOC(pixel, luma_size);
|
||||||
pic->u_data = MALLOC(pixel, chroma_size);
|
pic->u_data = MALLOC(pixel, chroma_size);
|
||||||
|
@ -301,12 +310,14 @@ picture *picture_alloc(const int32_t width, const int32_t height,
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Free memory allocated to picture
|
* \brief Free memory allocated to picture (if we have no reference left)
|
||||||
* \param pic picture pointer
|
* \param pic picture pointer
|
||||||
* \return 1 on success, 0 on failure
|
* \return 1 on success, 0 on failure
|
||||||
*/
|
*/
|
||||||
int picture_free(picture * const pic)
|
int picture_free(picture * const pic)
|
||||||
{
|
{
|
||||||
|
int32_t new_refcount = ATOMIC_DEC(&(pic->refcount));
|
||||||
|
if (new_refcount > 0) return 1;
|
||||||
free(pic->u_data);
|
free(pic->u_data);
|
||||||
free(pic->v_data);
|
free(pic->v_data);
|
||||||
free(pic->y_data);
|
free(pic->y_data);
|
||||||
|
|
|
@ -120,6 +120,7 @@ typedef struct picture_struct
|
||||||
int32_t height_in_lcu; //!< \brief Picture width in number of LCU's.
|
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.
|
int32_t width_in_lcu; //!< \brief Picture height in number of LCU's.
|
||||||
uint8_t referenced; //!< \brief Whether this picture is referenced.
|
uint8_t referenced; //!< \brief Whether this picture is referenced.
|
||||||
|
int32_t refcount; //!< \brief Number of references in reflist to the picture
|
||||||
cu_info* cu_array; //!< \brief Info for each CU at each depth.
|
cu_info* cu_array; //!< \brief Info for each CU at each depth.
|
||||||
uint8_t type;
|
uint8_t type;
|
||||||
uint8_t slicetype;
|
uint8_t slicetype;
|
||||||
|
@ -224,7 +225,7 @@ picture_list * picture_list_init(int size);
|
||||||
int picture_list_resize(picture_list *list, unsigned size);
|
int picture_list_resize(picture_list *list, unsigned size);
|
||||||
int picture_list_destroy(picture_list *list);
|
int picture_list_destroy(picture_list *list);
|
||||||
int picture_list_add(picture_list *list, picture *pic);
|
int picture_list_add(picture_list *list, picture *pic);
|
||||||
int picture_list_rem(picture_list *list, unsigned n, int8_t destroy);
|
int picture_list_rem(picture_list *list, unsigned n);
|
||||||
|
|
||||||
typedef unsigned (*cost_16bit_nxn_func)(pixel *block1, pixel *block2);
|
typedef unsigned (*cost_16bit_nxn_func)(pixel *block1, pixel *block2);
|
||||||
|
|
||||||
|
|
37
src/threads.h
Normal file
37
src/threads.h
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
#ifndef THREADS_H_
|
||||||
|
#define THREADS_H_
|
||||||
|
/*****************************************************************************
|
||||||
|
* This file is part of Kvazaar HEVC encoder.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013-2014 Tampere University of Technology and others (see
|
||||||
|
* 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/>.
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
|
|
||||||
|
#define ATOMIC_INC(ptr) __sync_add_and_fetch((volatile int32_t*)ptr, 1)
|
||||||
|
#define ATOMIC_DEC(ptr) __sync_add_and_fetch((volatile int32_t*)ptr, -1)
|
||||||
|
|
||||||
|
#else //__GNUC__
|
||||||
|
|
||||||
|
//TODO: we assume !GCC => Windows... this may be bad
|
||||||
|
#define ATOMIC_INC(ptr) InterlockedIncrement((volatile LONG*)ptr)
|
||||||
|
#define ATOMIC_DEC(ptr) InterlockedDecrement((volatile LONG*)ptr)
|
||||||
|
|
||||||
|
#endif //__GNUC__
|
||||||
|
|
||||||
|
#endif //THREADS_H_
|
Loading…
Reference in a new issue