mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-11-26 19:01:44 +02:00
avcodec/bitstream: try to make vlc init code inherently thread safe
also remove spinlock, it doesnt work on AIX Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
parent
f7f96cf4bc
commit
e6f9fc4adc
@ -163,7 +163,7 @@ static int build_table(VLC *vlc, int table_nb_bits, int nb_codes,
|
|||||||
int table_size, table_index, index, code_prefix, symbol, subtable_bits;
|
int table_size, table_index, index, code_prefix, symbol, subtable_bits;
|
||||||
int i, j, k, n, nb, inc;
|
int i, j, k, n, nb, inc;
|
||||||
uint32_t code;
|
uint32_t code;
|
||||||
VLC_TYPE (*table)[2];
|
volatile VLC_TYPE (*table)[2];
|
||||||
|
|
||||||
table_size = 1 << table_nb_bits;
|
table_size = 1 << table_nb_bits;
|
||||||
if (table_nb_bits > 30)
|
if (table_nb_bits > 30)
|
||||||
@ -172,7 +172,7 @@ static int build_table(VLC *vlc, int table_nb_bits, int nb_codes,
|
|||||||
av_dlog(NULL, "new table index=%d size=%d\n", table_index, table_size);
|
av_dlog(NULL, "new table index=%d size=%d\n", table_index, table_size);
|
||||||
if (table_index < 0)
|
if (table_index < 0)
|
||||||
return table_index;
|
return table_index;
|
||||||
table = &vlc->table[table_index];
|
table = (volatile VLC_TYPE (*)[2])&vlc->table[table_index];
|
||||||
|
|
||||||
/* first pass: map codes and compute auxiliary table sizes */
|
/* first pass: map codes and compute auxiliary table sizes */
|
||||||
for (i = 0; i < nb_codes; i++) {
|
for (i = 0; i < nb_codes; i++) {
|
||||||
@ -190,8 +190,9 @@ static int build_table(VLC *vlc, int table_nb_bits, int nb_codes,
|
|||||||
inc = 1 << n;
|
inc = 1 << n;
|
||||||
}
|
}
|
||||||
for (k = 0; k < nb; k++) {
|
for (k = 0; k < nb; k++) {
|
||||||
|
int bits = table[j][1];
|
||||||
av_dlog(NULL, "%4x: code=%d n=%d\n", j, i, n);
|
av_dlog(NULL, "%4x: code=%d n=%d\n", j, i, n);
|
||||||
if (table[j][1] /*bits*/ != 0) {
|
if (bits != 0 && bits != n) {
|
||||||
av_log(NULL, AV_LOG_ERROR, "incorrect codes\n");
|
av_log(NULL, AV_LOG_ERROR, "incorrect codes\n");
|
||||||
return AVERROR_INVALIDDATA;
|
return AVERROR_INVALIDDATA;
|
||||||
}
|
}
|
||||||
@ -226,7 +227,7 @@ static int build_table(VLC *vlc, int table_nb_bits, int nb_codes,
|
|||||||
if (index < 0)
|
if (index < 0)
|
||||||
return index;
|
return index;
|
||||||
/* note: realloc has been done, so reload tables */
|
/* note: realloc has been done, so reload tables */
|
||||||
table = &vlc->table[table_index];
|
table = (volatile VLC_TYPE (*)[2])&vlc->table[table_index];
|
||||||
table[j][0] = index; //code
|
table[j][0] = index; //code
|
||||||
av_assert0(table[j][0] == index);
|
av_assert0(table[j][0] == index);
|
||||||
i = k-1;
|
i = k-1;
|
||||||
@ -268,7 +269,7 @@ static int build_table(VLC *vlc, int table_nb_bits, int nb_codes,
|
|||||||
'use_static' should be set to 1 for tables, which should be freed
|
'use_static' should be set to 1 for tables, which should be freed
|
||||||
with av_free_static(), 0 if ff_free_vlc() will be used.
|
with av_free_static(), 0 if ff_free_vlc() will be used.
|
||||||
*/
|
*/
|
||||||
int ff_init_vlc_sparse(VLC *vlc, int nb_bits, int nb_codes,
|
int ff_init_vlc_sparse(VLC *vlc_arg, int nb_bits, int nb_codes,
|
||||||
const void *bits, int bits_wrap, int bits_size,
|
const void *bits, int bits_wrap, int bits_size,
|
||||||
const void *codes, int codes_wrap, int codes_size,
|
const void *codes, int codes_wrap, int codes_size,
|
||||||
const void *symbols, int symbols_wrap, int symbols_size,
|
const void *symbols, int symbols_wrap, int symbols_size,
|
||||||
@ -277,19 +278,16 @@ int ff_init_vlc_sparse(VLC *vlc, int nb_bits, int nb_codes,
|
|||||||
VLCcode *buf;
|
VLCcode *buf;
|
||||||
int i, j, ret;
|
int i, j, ret;
|
||||||
VLCcode localbuf[1500]; // the maximum currently needed is 1296 by rv34
|
VLCcode localbuf[1500]; // the maximum currently needed is 1296 by rv34
|
||||||
void *state;
|
VLC localvlc, *vlc;
|
||||||
|
|
||||||
|
vlc = vlc_arg;
|
||||||
vlc->bits = nb_bits;
|
vlc->bits = nb_bits;
|
||||||
if (flags & INIT_VLC_USE_NEW_STATIC) {
|
if (flags & INIT_VLC_USE_NEW_STATIC) {
|
||||||
while (state = avpriv_atomic_ptr_cas(&vlc->init_state, NULL, vlc)) {
|
|
||||||
if (state == vlc + 1) {
|
|
||||||
av_assert0(vlc->table_size && vlc->table_size == vlc->table_allocated);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
av_assert0(!vlc->table_size);
|
|
||||||
av_assert0(nb_codes + 1 <= FF_ARRAY_ELEMS(localbuf));
|
av_assert0(nb_codes + 1 <= FF_ARRAY_ELEMS(localbuf));
|
||||||
buf = localbuf;
|
buf = localbuf;
|
||||||
|
localvlc = *vlc_arg;
|
||||||
|
vlc = &localvlc;
|
||||||
|
vlc->table_size = 0;
|
||||||
} else {
|
} else {
|
||||||
vlc->table = NULL;
|
vlc->table = NULL;
|
||||||
vlc->table_allocated = 0;
|
vlc->table_allocated = 0;
|
||||||
@ -342,9 +340,9 @@ int ff_init_vlc_sparse(VLC *vlc, int nb_bits, int nb_codes,
|
|||||||
if (flags & INIT_VLC_USE_NEW_STATIC) {
|
if (flags & INIT_VLC_USE_NEW_STATIC) {
|
||||||
if(vlc->table_size != vlc->table_allocated)
|
if(vlc->table_size != vlc->table_allocated)
|
||||||
av_log(NULL, AV_LOG_ERROR, "needed %d had %d\n", vlc->table_size, vlc->table_allocated);
|
av_log(NULL, AV_LOG_ERROR, "needed %d had %d\n", vlc->table_size, vlc->table_allocated);
|
||||||
state = avpriv_atomic_ptr_cas(&vlc->init_state, vlc, vlc+1);
|
|
||||||
av_assert0(state == vlc);
|
|
||||||
av_assert0(ret >= 0);
|
av_assert0(ret >= 0);
|
||||||
|
*vlc_arg = *vlc;
|
||||||
} else {
|
} else {
|
||||||
av_free(buf);
|
av_free(buf);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
|
@ -64,7 +64,6 @@ typedef struct VLC {
|
|||||||
int bits;
|
int bits;
|
||||||
VLC_TYPE (*table)[2]; ///< code, bits
|
VLC_TYPE (*table)[2]; ///< code, bits
|
||||||
int table_size, table_allocated;
|
int table_size, table_allocated;
|
||||||
void * volatile init_state;
|
|
||||||
} VLC;
|
} VLC;
|
||||||
|
|
||||||
typedef struct RL_VLC_ELEM {
|
typedef struct RL_VLC_ELEM {
|
||||||
|
Loading…
Reference in New Issue
Block a user