mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-12-23 12:43:46 +02:00
fic: set pict_type/key_frame after (instead of during) slice decoding.
This fixes a race condition that was already documented in the source code, and is also reported by tsan in fate-fic-avi.
This commit is contained in:
parent
9e2050b698
commit
73f863d751
@ -34,6 +34,7 @@ typedef struct FICThreadContext {
|
||||
int slice_h;
|
||||
int src_size;
|
||||
int y_off;
|
||||
int p_frame;
|
||||
} FICThreadContext;
|
||||
|
||||
typedef struct FICContext {
|
||||
@ -133,16 +134,13 @@ static void fic_idct_put(uint8_t *dst, int stride, int16_t *block)
|
||||
}
|
||||
}
|
||||
static int fic_decode_block(FICContext *ctx, GetBitContext *gb,
|
||||
uint8_t *dst, int stride, int16_t *block)
|
||||
uint8_t *dst, int stride, int16_t *block, int *is_p)
|
||||
{
|
||||
int i, num_coeff;
|
||||
|
||||
/* Is it a skip block? */
|
||||
if (get_bits1(gb)) {
|
||||
/* This is a P-frame. */
|
||||
ctx->frame->key_frame = 0;
|
||||
ctx->frame->pict_type = AV_PICTURE_TYPE_P;
|
||||
|
||||
*is_p = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -182,7 +180,8 @@ static int fic_decode_slice(AVCodecContext *avctx, void *tdata)
|
||||
for (x = 0; x < (ctx->aligned_width >> !!p); x += 8) {
|
||||
int ret;
|
||||
|
||||
if ((ret = fic_decode_block(ctx, &gb, dst + x, stride, tctx->block)) != 0)
|
||||
if ((ret = fic_decode_block(ctx, &gb, dst + x, stride,
|
||||
tctx->block, &tctx->p_frame)) != 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -348,15 +347,6 @@ static int fic_decode_frame(AVCodecContext *avctx, void *data,
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the frametype to I initially. It will be set to P if the frame
|
||||
* has any dependencies (skip blocks). There will be a race condition
|
||||
* inside the slice decode function to set these, but we do not care.
|
||||
* since they will only ever be set to 0/P.
|
||||
*/
|
||||
ctx->frame->key_frame = 1;
|
||||
ctx->frame->pict_type = AV_PICTURE_TYPE_I;
|
||||
|
||||
/* Allocate slice data. */
|
||||
av_fast_malloc(&ctx->slice_data, &ctx->slice_data_size,
|
||||
nslices * sizeof(ctx->slice_data[0]));
|
||||
@ -398,6 +388,15 @@ static int fic_decode_frame(AVCodecContext *avctx, void *data,
|
||||
NULL, nslices, sizeof(ctx->slice_data[0]))) < 0)
|
||||
return ret;
|
||||
|
||||
ctx->frame->key_frame = 1;
|
||||
ctx->frame->pict_type = AV_PICTURE_TYPE_I;
|
||||
for (slice = 0; slice < nslices; slice++) {
|
||||
if (ctx->slice_data[slice].p_frame) {
|
||||
ctx->frame->key_frame = 0;
|
||||
ctx->frame->pict_type = AV_PICTURE_TYPE_P;
|
||||
break;
|
||||
}
|
||||
}
|
||||
av_frame_free(&ctx->final_frame);
|
||||
ctx->final_frame = av_frame_clone(ctx->frame);
|
||||
if (!ctx->final_frame) {
|
||||
|
Loading…
Reference in New Issue
Block a user