@@ -40,8 +40,8 @@
#include "apng.h"
#include "png.h"
#include "pngdsp.h"
+#include "progressframe.h"
#include "thread.h"
-#include "threadframe.h"
#include "zlib_wrapper.h"
#include <zlib.h>
@@ -61,8 +61,8 @@ typedef struct PNGDecContext {
AVCodecContext *avctx;
GetByteContext gb;
- ThreadFrame last_picture;
- ThreadFrame picture;
+ ProgressFrame last_picture;
+ ProgressFrame picture;
AVDictionary *frame_metadata;
@@ -815,7 +815,7 @@ static int decode_idat_chunk(AVCodecContext *avctx, PNGDecContext *s,
s->bpp += byte_depth;
}
- ff_thread_release_ext_buffer(avctx, &s->picture);
+ ff_thread_progress_unref(avctx, &s->picture);
if (s->dispose_op == APNG_DISPOSE_OP_PREVIOUS) {
/* We only need a buffer for the current picture. */
ret = ff_thread_get_buffer(avctx, p, 0);
@@ -824,8 +824,8 @@ static int decode_idat_chunk(AVCodecContext *avctx, PNGDecContext *s,
} else if (s->dispose_op == APNG_DISPOSE_OP_BACKGROUND) {
/* We need a buffer for the current picture as well as
* a buffer for the reference to retain. */
- ret = ff_thread_get_ext_buffer(avctx, &s->picture,
- AV_GET_BUFFER_FLAG_REF);
+ ret = ff_thread_progress_get_buffer(avctx, &s->picture,
+ AV_GET_BUFFER_FLAG_REF);
if (ret < 0)
return ret;
ret = ff_thread_get_buffer(avctx, p, 0);
@@ -833,8 +833,9 @@ static int decode_idat_chunk(AVCodecContext *avctx, PNGDecContext *s,
return ret;
} else {
/* The picture output this time and the reference to retain coincide. */
- if ((ret = ff_thread_get_ext_buffer(avctx, &s->picture,
- AV_GET_BUFFER_FLAG_REF)) < 0)
+ ret = ff_thread_progress_get_buffer(avctx, &s->picture,
+ AV_GET_BUFFER_FLAG_REF);
+ if (ret < 0)
return ret;
ret = av_frame_ref(p, s->picture.f);
if (ret < 0)
@@ -1195,7 +1196,7 @@ static void handle_p_frame_png(PNGDecContext *s, AVFrame *p)
ls = FFMIN(ls, s->width * s->bpp);
- ff_thread_await_progress(&s->last_picture, INT_MAX, 0);
+ ff_thread_progress_await(&s->last_picture, INT_MAX);
for (j = 0; j < s->height; j++) {
for (i = 0; i < ls; i++)
pd[i] += pd_last[i];
@@ -1227,7 +1228,7 @@ static int handle_p_frame_apng(AVCodecContext *avctx, PNGDecContext *s,
return AVERROR_PATCHWELCOME;
}
- ff_thread_await_progress(&s->last_picture, INT_MAX, 0);
+ ff_thread_progress_await(&s->last_picture, INT_MAX);
// copy unchanged rectangles from the last frame
for (y = 0; y < s->y_offset; y++)
@@ -1594,7 +1595,7 @@ exit_loop:
}
/* handle P-frames only if a predecessor frame is available */
- if (s->last_picture.f->data[0]) {
+ if (s->last_picture.f) {
if ( !(avpkt->flags & AV_PKT_FLAG_KEY) && avctx->codec_tag != AV_RL32("MPNG")
&& s->last_picture.f->width == p->width
&& s->last_picture.f->height== p->height
@@ -1611,12 +1612,11 @@ exit_loop:
if (CONFIG_APNG_DECODER && s->dispose_op == APNG_DISPOSE_OP_BACKGROUND)
apng_reset_background(s, p);
- ff_thread_report_progress(&s->picture, INT_MAX, 0);
-
- return 0;
-
+ ret = 0;
fail:
- ff_thread_report_progress(&s->picture, INT_MAX, 0);
+ if (s->picture.f)
+ ff_thread_progress_report(&s->picture, INT_MAX);
+
return ret;
}
@@ -1703,8 +1703,8 @@ static int decode_frame_png(AVCodecContext *avctx, AVFrame *p,
goto the_end;
if (!(avctx->active_thread_type & FF_THREAD_FRAME)) {
- ff_thread_release_ext_buffer(avctx, &s->last_picture);
- FFSWAP(ThreadFrame, s->picture, s->last_picture);
+ ff_thread_progress_unref(avctx, &s->last_picture);
+ FFSWAP(ProgressFrame, s->picture, s->last_picture);
}
*got_frame = 1;
@@ -1756,10 +1756,10 @@ static int decode_frame_apng(AVCodecContext *avctx, AVFrame *p,
if (!(avctx->active_thread_type & FF_THREAD_FRAME)) {
if (s->dispose_op == APNG_DISPOSE_OP_PREVIOUS) {
- ff_thread_release_ext_buffer(avctx, &s->picture);
+ ff_thread_progress_unref(avctx, &s->picture);
} else {
- ff_thread_release_ext_buffer(avctx, &s->last_picture);
- FFSWAP(ThreadFrame, s->picture, s->last_picture);
+ ff_thread_progress_unref(avctx, &s->last_picture);
+ FFSWAP(ProgressFrame, s->picture, s->last_picture);
}
}
@@ -1773,8 +1773,7 @@ static int update_thread_context(AVCodecContext *dst, const AVCodecContext *src)
{
PNGDecContext *psrc = src->priv_data;
PNGDecContext *pdst = dst->priv_data;
- ThreadFrame *src_frame = NULL;
- int ret;
+ const ProgressFrame *src_frame;
if (dst == src)
return 0;
@@ -1799,12 +1798,7 @@ static int update_thread_context(AVCodecContext *dst, const AVCodecContext *src)
src_frame = psrc->dispose_op == APNG_DISPOSE_OP_PREVIOUS ?
&psrc->last_picture : &psrc->picture;
- ff_thread_release_ext_buffer(dst, &pdst->last_picture);
- if (src_frame && src_frame->f->data[0]) {
- ret = ff_thread_ref_frame(&pdst->last_picture, src_frame);
- if (ret < 0)
- return ret;
- }
+ ff_thread_progress_replace(dst, &pdst->last_picture, src_frame);
return 0;
}
@@ -1817,10 +1811,6 @@ static av_cold int png_dec_init(AVCodecContext *avctx)
avctx->color_range = AVCOL_RANGE_JPEG;
s->avctx = avctx;
- s->last_picture.f = av_frame_alloc();
- s->picture.f = av_frame_alloc();
- if (!s->last_picture.f || !s->picture.f)
- return AVERROR(ENOMEM);
ff_pngdsp_init(&s->dsp);
@@ -1831,10 +1821,8 @@ static av_cold int png_dec_end(AVCodecContext *avctx)
{
PNGDecContext *s = avctx->priv_data;
- ff_thread_release_ext_buffer(avctx, &s->last_picture);
- av_frame_free(&s->last_picture.f);
- ff_thread_release_ext_buffer(avctx, &s->picture);
- av_frame_free(&s->picture.f);
+ ff_thread_progress_unref(avctx, &s->last_picture);
+ ff_thread_progress_unref(avctx, &s->picture);
av_freep(&s->buffer);
s->buffer_size = 0;
av_freep(&s->last_row);
@@ -1862,6 +1850,7 @@ const FFCodec ff_apng_decoder = {
UPDATE_THREAD_CONTEXT(update_thread_context),
.p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
.caps_internal = FF_CODEC_CAP_INIT_CLEANUP |
+ FF_CODEC_CAP_USES_PROGRESSFRAMES |
FF_CODEC_CAP_ICC_PROFILES,
};
#endif
@@ -1880,6 +1869,7 @@ const FFCodec ff_png_decoder = {
.p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
.caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM |
FF_CODEC_CAP_INIT_CLEANUP |
+ FF_CODEC_CAP_USES_PROGRESSFRAMES |
FF_CODEC_CAP_ICC_PROFILES,
};
#endif
Avoids implicit av_frame_ref() and therefore allocations and error checks. It also avoids explicitly allocating the AVFrames (done implicitly when getting the buffer). Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com> --- libavcodec/pngdec.c | 64 +++++++++++++++++++-------------------------- 1 file changed, 27 insertions(+), 37 deletions(-)