mirror of
https://github.com/ultravideo/uvg266.git
synced 2024-11-24 02:24:07 +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) {
|
||||
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;
|
||||
|
@ -1375,21 +1375,25 @@ static void encode_VUI(encoder_state * const encoder_state)
|
|||
|
||||
void encoder_next_frame(encoder_state *encoder_state) {
|
||||
const encoder_control * const encoder = encoder_state->encoder_control;
|
||||
picture *old_pic;
|
||||
|
||||
// Remove the ref pic (if present)
|
||||
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
|
||||
picture_list_add(encoder_state->ref, encoder_state->cur_pic);
|
||||
// Allocate new memory to current picture
|
||||
old_pic = encoder_state->cur_pic;
|
||||
// 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);
|
||||
|
||||
// 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_u,encoder_state->ref->pics[0]->coeff_u);
|
||||
MOVE_POINTER(encoder_state->cur_pic->coeff_v,encoder_state->ref->pics[0]->coeff_v);
|
||||
MOVE_POINTER(encoder_state->cur_pic->coeff_y,old_pic->coeff_y);
|
||||
MOVE_POINTER(encoder_state->cur_pic->coeff_u,old_pic->coeff_u);
|
||||
MOVE_POINTER(encoder_state->cur_pic->coeff_v,old_pic->coeff_v);
|
||||
|
||||
picture_free(old_pic);
|
||||
|
||||
encoder_state->frame++;
|
||||
encoder_state->poc++;
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
* \file
|
||||
*/
|
||||
|
||||
#include "threads.h"
|
||||
#include "picture.h"
|
||||
#include "strategyselector.h"
|
||||
|
||||
|
@ -192,6 +193,11 @@ int picture_list_destroy(picture_list *list)
|
|||
*/
|
||||
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;
|
||||
if (list->size == list->used_size) {
|
||||
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
|
||||
* \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
|
||||
if (n >= list->used_size)
|
||||
|
@ -220,19 +226,21 @@ int picture_list_rem(picture_list *list, unsigned n, int8_t destroy)
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (destroy) {
|
||||
picture_free(list->pics[n]);
|
||||
list->pics[n] = NULL;
|
||||
if (!picture_free(list->pics[n])) {
|
||||
fprintf(stderr, "Could not free picture!\n");
|
||||
assert(0); //Stop here
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// The last item is easy to remove
|
||||
if (n == list->used_size - 1) {
|
||||
list->pics[n] = NULL;
|
||||
list->used_size--;
|
||||
} else {
|
||||
int i = n;
|
||||
// Shift all following pics one backward in the list
|
||||
for (; n < list->used_size - 1; ++n) {
|
||||
list->pics[n] = list->pics[n + 1];
|
||||
for (i = n; i < list->used_size - 1; ++i) {
|
||||
list->pics[i] = list->pics[i + 1];
|
||||
}
|
||||
list->pics[list->used_size - 1] = NULL;
|
||||
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->height_in_lcu = height_in_lcu;
|
||||
pic->referenced = 0;
|
||||
pic->refcount = 1; //We give a reference to caller
|
||||
// Allocate buffers
|
||||
pic->y_data = MALLOC(pixel, luma_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
|
||||
* \return 1 on success, 0 on failure
|
||||
*/
|
||||
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->v_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 width_in_lcu; //!< \brief Picture height in number of LCU's.
|
||||
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.
|
||||
uint8_t type;
|
||||
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_destroy(picture_list *list);
|
||||
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);
|
||||
|
||||
|
|
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