diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2013-09-01 22:38:43 +0200 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2013-09-01 23:22:06 +0200 |
commit | 21dc3a3cc23c624630a4379f08a6efe0230de37a (patch) | |
tree | e0b8693a41734413ce15d84c47f4df500e8f9309 /libavcodec/ffv1dec.c | |
parent | c72cca5a44d8a83e097a97a13990d421ba7a4c5d (diff) | |
download | ffmpeg-21dc3a3cc23c624630a4379f08a6efe0230de37a.tar.gz |
avcodec/ffv1dec: reorganize thread init/update
This moves some allocations to init, reducing possible failure modes in update.
Always copies from the previous context instead of just during init
Fixes Ticket2923
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavcodec/ffv1dec.c')
-rw-r--r-- | libavcodec/ffv1dec.c | 61 |
1 files changed, 46 insertions, 15 deletions
diff --git a/libavcodec/ffv1dec.c b/libavcodec/ffv1dec.c index 70904eaf29..c600ce8d25 100644 --- a/libavcodec/ffv1dec.c +++ b/libavcodec/ffv1dec.c @@ -942,7 +942,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac static int init_thread_copy(AVCodecContext *avctx) { FFV1Context *f = avctx->priv_data; - int i; + int i, ret; f->picture.f = NULL; f->last_picture.f = NULL; @@ -955,9 +955,43 @@ static int init_thread_copy(AVCodecContext *avctx) f->context_count[i] * sizeof(*f->initial_states[i])); } + f->picture.f = av_frame_alloc(); + f->last_picture.f = av_frame_alloc(); + + if ((ret = ffv1_init_slice_contexts(f)) < 0) + return ret; + return 0; } +static void copy_fields(FFV1Context *fsdst, FFV1Context *fssrc, FFV1Context *fsrc) +{ + fsdst->version = fsrc->version; + fsdst->micro_version = fsrc->micro_version; + fsdst->chroma_planes = fsrc->chroma_planes; + fsdst->chroma_h_shift = fsrc->chroma_h_shift; + fsdst->chroma_v_shift = fsrc->chroma_v_shift; + fsdst->transparency = fsrc->transparency; + fsdst->plane_count = fsrc->plane_count; + fsdst->ac = fsrc->ac; + fsdst->colorspace = fsrc->colorspace; + + fsdst->ec = fsrc->ec; + fsdst->intra = fsrc->intra; + fsdst->slice_damaged = fssrc->slice_damaged; + fsdst->key_frame_ok = fsrc->key_frame_ok; + + fsdst->bits_per_raw_sample = fsrc->bits_per_raw_sample; + fsdst->packed_at_lsb = fsrc->packed_at_lsb; + fsdst->slice_count = fsrc->slice_count; + if (fsrc->version<3){ + fsdst->slice_x = fssrc->slice_x; + fsdst->slice_y = fssrc->slice_y; + fsdst->slice_width = fssrc->slice_width; + fsdst->slice_height = fssrc->slice_height; + } +} + static int update_thread_context(AVCodecContext *dst, const AVCodecContext *src) { FFV1Context *fsrc = src->priv_data; @@ -967,33 +1001,30 @@ static int update_thread_context(AVCodecContext *dst, const AVCodecContext *src) if (dst == src) return 0; - if (!fdst->picture.f) { + { FFV1Context bak = *fdst; memcpy(fdst, fsrc, sizeof(*fdst)); memcpy(fdst->initial_states, bak.initial_states, sizeof(fdst->initial_states)); - - fdst->picture.f = av_frame_alloc(); - fdst->last_picture.f = av_frame_alloc(); - - if ((ret = ffv1_init_slice_contexts(fdst)) < 0) - return ret; + memcpy(fdst->slice_context, bak.slice_context , sizeof(fdst->slice_context)); + fdst->picture = bak.picture; + fdst->last_picture = bak.last_picture; + for (i = 0; i<fdst->num_h_slices * fdst->num_v_slices; i++) { + FFV1Context *fssrc = fsrc->slice_context[i]; + FFV1Context *fsdst = fdst->slice_context[i]; + copy_fields(fsdst, fssrc, fsrc); + } + av_assert0(!fdst->plane[0].state); + av_assert0(!fdst->sample_buffer); } av_assert1(fdst->slice_count == fsrc->slice_count); - fdst->key_frame_ok = fsrc->key_frame_ok; ff_thread_release_buffer(dst, &fdst->picture); if (fsrc->picture.f->data[0]) { if ((ret = ff_thread_ref_frame(&fdst->picture, &fsrc->picture)) < 0) return ret; } - for (i = 0; i < fdst->slice_count; i++) { - FFV1Context *fsdst = fdst->slice_context[i]; - FFV1Context *fssrc = fsrc->slice_context[i]; - - fsdst->slice_damaged = fssrc->slice_damaged; - } fdst->fsrc = fsrc; |