aboutsummaryrefslogtreecommitdiffstats
path: root/libavcodec/fic.c
diff options
context:
space:
mode:
authorRonald S. Bultje <rsbultje@gmail.com>2017-03-28 19:52:07 -0400
committerRonald S. Bultje <rsbultje@gmail.com>2017-03-31 08:26:23 -0400
commit73f863d751df84db7a0ca1bd83cdff1b95dc94dd (patch)
treea489eff8278b7916b8db2e63f2409f87507b75e7 /libavcodec/fic.c
parent9e2050b698b204bcc4af39e014b3e621294a114a (diff)
downloadffmpeg-73f863d751df84db7a0ca1bd83cdff1b95dc94dd.tar.gz
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.
Diffstat (limited to 'libavcodec/fic.c')
-rw-r--r--libavcodec/fic.c29
1 files changed, 14 insertions, 15 deletions
diff --git a/libavcodec/fic.c b/libavcodec/fic.c
index d3952a4c01..2bec3d7b03 100644
--- a/libavcodec/fic.c
+++ b/libavcodec/fic.c
@@ -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) {