|
|
|
@ -326,6 +326,42 @@ static int decode_slice(AVCodecContext *c, void *arg) |
|
|
|
|
int width, height, x, y, ret; |
|
|
|
|
const int ps = av_pix_fmt_desc_get(c->pix_fmt)->comp[0].step_minus1 + 1; |
|
|
|
|
AVFrame * const p = f->cur; |
|
|
|
|
int i, si; |
|
|
|
|
|
|
|
|
|
for( si=0; fs != f->slice_context[si]; si ++) |
|
|
|
|
; |
|
|
|
|
|
|
|
|
|
if(f->fsrc && !p->key_frame) |
|
|
|
|
ff_thread_await_progress(&f->last_picture, si, 0); |
|
|
|
|
|
|
|
|
|
if(f->fsrc && !p->key_frame) { |
|
|
|
|
FFV1Context *fssrc = f->fsrc->slice_context[si]; |
|
|
|
|
FFV1Context *fsdst = f->slice_context[si]; |
|
|
|
|
av_assert1(fsdst->plane_count == fssrc->plane_count); |
|
|
|
|
av_assert1(fsdst == fs); |
|
|
|
|
|
|
|
|
|
if (!p->key_frame) |
|
|
|
|
fsdst->slice_damaged |= fssrc->slice_damaged; |
|
|
|
|
|
|
|
|
|
for (i = 0; i < f->plane_count; i++) { |
|
|
|
|
PlaneContext *psrc = &fssrc->plane[i]; |
|
|
|
|
PlaneContext *pdst = &fsdst->plane[i]; |
|
|
|
|
|
|
|
|
|
av_free(pdst->state); |
|
|
|
|
av_free(pdst->vlc_state); |
|
|
|
|
memcpy(pdst, psrc, sizeof(*pdst)); |
|
|
|
|
pdst->state = NULL; |
|
|
|
|
pdst->vlc_state = NULL; |
|
|
|
|
|
|
|
|
|
if (fssrc->ac) { |
|
|
|
|
pdst->state = av_malloc(CONTEXT_SIZE * psrc->context_count); |
|
|
|
|
memcpy(pdst->state, psrc->state, CONTEXT_SIZE * psrc->context_count); |
|
|
|
|
} else { |
|
|
|
|
pdst->vlc_state = av_malloc(sizeof(*pdst->vlc_state) * psrc->context_count); |
|
|
|
|
memcpy(pdst->vlc_state, psrc->vlc_state, sizeof(*pdst->vlc_state) * psrc->context_count); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (f->version > 2) { |
|
|
|
|
if (ffv1_init_slice_state(f, fs) < 0) |
|
|
|
@ -386,6 +422,8 @@ static int decode_slice(AVCodecContext *c, void *arg) |
|
|
|
|
|
|
|
|
|
emms_c(); |
|
|
|
|
|
|
|
|
|
ff_thread_report_progress(&f->picture, si, 0); |
|
|
|
|
|
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -724,6 +762,8 @@ static av_cold int decode_init(AVCodecContext *avctx) |
|
|
|
|
if ((ret = ffv1_init_slice_contexts(f)) < 0) |
|
|
|
|
return ret; |
|
|
|
|
|
|
|
|
|
avctx->internal->allocate_progress = 1; |
|
|
|
|
|
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -744,6 +784,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac |
|
|
|
|
|
|
|
|
|
f->cur = p = f->picture.f; |
|
|
|
|
|
|
|
|
|
f->avctx = avctx; |
|
|
|
|
ff_init_range_decoder(c, buf, buf_size); |
|
|
|
|
ff_build_rac_states(c, 0.05 * (1LL << 32), 256 - 8); |
|
|
|
|
|
|
|
|
@ -770,6 +811,8 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac |
|
|
|
|
av_log(avctx, AV_LOG_DEBUG, "ver:%d keyframe:%d coder:%d ec:%d slices:%d bps:%d\n", |
|
|
|
|
f->version, p->key_frame, f->ac, f->ec, f->slice_count, f->avctx->bits_per_raw_sample); |
|
|
|
|
|
|
|
|
|
ff_thread_finish_setup(avctx); |
|
|
|
|
|
|
|
|
|
buf_p = buf + buf_size; |
|
|
|
|
for (i = f->slice_count - 1; i >= 0; i--) { |
|
|
|
|
FFV1Context *fs = f->slice_context[i]; |
|
|
|
@ -822,6 +865,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac |
|
|
|
|
if (fs->slice_damaged && f->last_picture.f->data[0]) { |
|
|
|
|
const uint8_t *src[4]; |
|
|
|
|
uint8_t *dst[4]; |
|
|
|
|
ff_thread_await_progress(&f->last_picture, INT_MAX, 0); |
|
|
|
|
for (j = 0; j < 4; j++) { |
|
|
|
|
int sh = (j==1 || j==2) ? f->chroma_h_shift : 0; |
|
|
|
|
int sv = (j==1 || j==2) ? f->chroma_v_shift : 0; |
|
|
|
@ -837,6 +881,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac |
|
|
|
|
fs->slice_height); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
ff_thread_report_progress(&f->picture, INT_MAX, 0); |
|
|
|
|
|
|
|
|
|
f->picture_number++; |
|
|
|
|
|
|
|
|
@ -854,18 +899,58 @@ 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 ret, i; |
|
|
|
|
|
|
|
|
|
for (i = 0; i < f->quant_table_count; i++) { |
|
|
|
|
void *p = f->initial_states[i]; |
|
|
|
|
f->initial_states[i] = av_malloc(f->context_count[i] * sizeof(*f->initial_states[i])); |
|
|
|
|
if (!f->initial_states[i]) |
|
|
|
|
return AVERROR(ENOMEM); |
|
|
|
|
memcpy(f->initial_states[i], p, f->context_count[i] * sizeof(*f->initial_states[i])); |
|
|
|
|
f->picture.f = NULL; |
|
|
|
|
f->last_picture.f = NULL; |
|
|
|
|
f->sample_buffer = NULL; |
|
|
|
|
f->quant_table_count = 0; |
|
|
|
|
f->slice_count = 0; |
|
|
|
|
|
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static int update_thread_context(AVCodecContext *dst, const AVCodecContext *src) |
|
|
|
|
{ |
|
|
|
|
FFV1Context *fsrc = src->priv_data; |
|
|
|
|
FFV1Context *fdst = dst->priv_data; |
|
|
|
|
int i, ret; |
|
|
|
|
|
|
|
|
|
if (dst == src) |
|
|
|
|
return 0; |
|
|
|
|
|
|
|
|
|
if (!fdst->quant_table_count) { |
|
|
|
|
memcpy(fdst, fsrc, sizeof(*fdst)); |
|
|
|
|
|
|
|
|
|
for (i = 0; i < fdst->quant_table_count; i++) { |
|
|
|
|
fdst->initial_states[i] = av_malloc(fdst->context_count[i] * sizeof(*fdst->initial_states[i])); |
|
|
|
|
memcpy(fdst->initial_states[i], fsrc->initial_states[i], fdst->context_count[i] * sizeof(*fdst->initial_states[i])); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if ((ret = ffv1_init_slice_contexts(f)) < 0) |
|
|
|
|
fdst->picture.f = av_frame_alloc(); |
|
|
|
|
fdst->last_picture.f = av_frame_alloc(); |
|
|
|
|
|
|
|
|
|
if ((ret = ffv1_init_slice_contexts(fdst)) < 0) |
|
|
|
|
return ret; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
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; |
|
|
|
|
|
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -878,7 +963,8 @@ AVCodec ff_ffv1_decoder = { |
|
|
|
|
.close = ffv1_close, |
|
|
|
|
.decode = decode_frame, |
|
|
|
|
.init_thread_copy = init_thread_copy, |
|
|
|
|
.update_thread_context = update_thread_context, |
|
|
|
|
.capabilities = CODEC_CAP_DR1 /*| CODEC_CAP_DRAW_HORIZ_BAND*/ | |
|
|
|
|
CODEC_CAP_SLICE_THREADS, |
|
|
|
|
CODEC_CAP_FRAME_THREADS | CODEC_CAP_SLICE_THREADS, |
|
|
|
|
.long_name = NULL_IF_CONFIG_SMALL("FFmpeg video codec #1"), |
|
|
|
|
}; |
|
|
|
|