From 759001c534287a96dc96d1e274665feb7059145d Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Wed, 21 Nov 2012 21:34:46 +0100 Subject: [PATCH] lavc decoders: work with refcounted frames. --- doc/multithreading.txt | 5 + libavcodec/4xm.c | 83 ++--- libavcodec/8bps.c | 30 +- libavcodec/8svx.c | 2 +- libavcodec/aacdec.c | 3 +- libavcodec/aasc.c | 22 +- libavcodec/ac3dec.c | 2 +- libavcodec/adpcm.c | 2 +- libavcodec/adxdec.c | 2 +- libavcodec/alac.c | 2 +- libavcodec/alsdec.c | 2 +- libavcodec/amrnbdec.c | 2 +- libavcodec/amrwbdec.c | 2 +- libavcodec/anm.c | 26 +- libavcodec/ansi.c | 57 +-- libavcodec/apedec.c | 2 +- libavcodec/asvdec.c | 40 +- libavcodec/atrac1.c | 2 +- libavcodec/atrac3.c | 2 +- libavcodec/aura.c | 42 +-- libavcodec/avcodec.h | 123 +++++- libavcodec/avs.c | 10 +- libavcodec/bethsoftvideo.c | 13 +- libavcodec/bfi.c | 29 +- libavcodec/bink.c | 67 ++-- libavcodec/binkaudio.c | 2 +- libavcodec/bmp.c | 34 +- libavcodec/bmv.c | 30 +- libavcodec/c93.c | 17 +- libavcodec/cavs.c | 18 +- libavcodec/cavsdec.c | 33 +- libavcodec/cdgraphics.c | 64 ++-- libavcodec/cdxl.c | 36 +- libavcodec/cinepak.c | 13 +- libavcodec/cljr.c | 56 +-- libavcodec/cllc.c | 22 +- libavcodec/cngdec.c | 2 +- libavcodec/cook.c | 2 +- libavcodec/cscd.c | 32 +- libavcodec/cyuv.c | 36 +- libavcodec/dcadec.c | 2 +- libavcodec/dfa.c | 20 +- libavcodec/dnxhddec.c | 58 ++- libavcodec/dpcm.c | 2 +- libavcodec/dpx.c | 34 +- libavcodec/dsicinav.c | 14 +- libavcodec/dvdec.c | 11 +- libavcodec/dxa.c | 51 ++- libavcodec/dxtory.c | 23 +- libavcodec/dxva2_h264.c | 10 +- libavcodec/eacmv.c | 87 +++-- libavcodec/eamad.c | 59 ++- libavcodec/eatgq.c | 64 ++-- libavcodec/eatgv.c | 74 ++-- libavcodec/eatqi.c | 29 +- libavcodec/error_resilience.c | 140 +++---- libavcodec/escape124.c | 28 +- libavcodec/ffv1.c | 5 +- libavcodec/ffv1.h | 2 + libavcodec/ffv1dec.c | 43 ++- libavcodec/flacdec.c | 2 +- libavcodec/flashsv.c | 21 +- libavcodec/flicvideo.c | 19 +- libavcodec/fraps.c | 34 +- libavcodec/frwu.c | 24 +- libavcodec/g722dec.c | 2 +- libavcodec/g723_1.c | 2 +- libavcodec/g726.c | 2 +- libavcodec/gifdec.c | 25 +- libavcodec/gsmdec.c | 2 +- libavcodec/h261dec.c | 11 +- libavcodec/h263.c | 48 +-- libavcodec/h263dec.c | 12 +- libavcodec/h264.c | 420 ++++++++++++--------- libavcodec/h264.h | 13 +- libavcodec/h264_cabac.c | 22 +- libavcodec/h264_cavlc.c | 8 +- libavcodec/h264_direct.c | 50 +-- libavcodec/h264_loopfilter.c | 34 +- libavcodec/h264_mb_template.c | 4 +- libavcodec/h264_mc_template.c | 2 +- libavcodec/h264_mvpred.h | 38 +- libavcodec/h264_refs.c | 64 ++-- libavcodec/huffyuvdec.c | 37 +- libavcodec/idcinvideo.c | 38 +- libavcodec/iff.c | 39 +- libavcodec/imc.c | 2 +- libavcodec/indeo2.c | 15 +- libavcodec/indeo3.c | 20 +- libavcodec/internal.h | 70 ++-- libavcodec/interplayvideo.c | 137 ++++--- libavcodec/intrax8.c | 2 +- libavcodec/ituh263dec.c | 26 +- libavcodec/ituh263enc.c | 6 +- libavcodec/ivi_common.c | 21 +- libavcodec/ivi_common.h | 1 - libavcodec/jvdec.c | 13 +- libavcodec/kgv1dec.c | 23 +- libavcodec/kmvc.c | 31 +- libavcodec/lagarith.c | 21 +- libavcodec/lcldec.c | 59 ++- libavcodec/libgsm.c | 2 +- libavcodec/libilbc.c | 2 +- libavcodec/libopencore-amr.c | 2 +- libavcodec/libopenjpegdec.c | 31 +- libavcodec/libopusdec.c | 2 +- libavcodec/libschroedingerdec.c | 29 +- libavcodec/libspeexdec.c | 2 +- libavcodec/libvpxdec.c | 16 +- libavcodec/ljpegenc.c | 5 +- libavcodec/loco.c | 22 +- libavcodec/mace.c | 2 +- libavcodec/mdec.c | 46 +-- libavcodec/mimic.c | 94 +++-- libavcodec/mjpegbdec.c | 16 +- libavcodec/mjpegdec.c | 36 +- libavcodec/mlpdec.c | 2 +- libavcodec/mmvideo.c | 14 +- libavcodec/motion_est.c | 62 ++-- libavcodec/motionpixels.c | 15 +- libavcodec/mpc7.c | 2 +- libavcodec/mpc8.c | 2 +- libavcodec/mpeg12.c | 59 +-- libavcodec/mpeg4video.c | 8 +- libavcodec/mpeg4videodec.c | 85 +++-- libavcodec/mpeg4videoenc.c | 12 +- libavcodec/mpegaudiodec.c | 4 +- libavcodec/mpegvideo.c | 589 +++++++++++++++++------------ libavcodec/mpegvideo.h | 57 ++- libavcodec/mpegvideo_enc.c | 102 +++-- libavcodec/mpegvideo_motion.c | 2 +- libavcodec/mpegvideo_xvmc.c | 2 +- libavcodec/msmpeg4.c | 2 +- libavcodec/msrle.c | 12 +- libavcodec/mss1.c | 13 +- libavcodec/mss2.c | 57 ++- libavcodec/mss3.c | 17 +- libavcodec/mss4.c | 18 +- libavcodec/msvideo1.c | 15 +- libavcodec/mxpegdec.c | 22 +- libavcodec/nellymoserdec.c | 2 +- libavcodec/nuv.c | 18 +- libavcodec/options.c | 4 +- libavcodec/options_table.h | 1 + libavcodec/pcm-mpeg.c | 2 +- libavcodec/pcm.c | 2 +- libavcodec/pcx.c | 35 +- libavcodec/pictordec.c | 41 +- libavcodec/pngdec.c | 39 +- libavcodec/pnm.c | 10 - libavcodec/pnm.h | 1 - libavcodec/pnmdec.c | 20 +- libavcodec/proresdec.c | 39 +- libavcodec/pthread.c | 172 +++++---- libavcodec/ptx.c | 35 +- libavcodec/qcelpdec.c | 2 +- libavcodec/qdm2.c | 2 +- libavcodec/qdrw.c | 36 +- libavcodec/qpeg.c | 11 +- libavcodec/qtrle.c | 12 +- libavcodec/r210dec.c | 23 +- libavcodec/ra144dec.c | 2 +- libavcodec/ra288.c | 2 +- libavcodec/ralf.c | 2 +- libavcodec/rawdec.c | 95 +++-- libavcodec/rl2.c | 17 +- libavcodec/roqvideodec.c | 28 +- libavcodec/roqvideoenc.c | 44 ++- libavcodec/rpza.c | 12 +- libavcodec/rv10.c | 11 +- libavcodec/rv30.c | 10 +- libavcodec/rv34.c | 171 +++++---- libavcodec/rv40.c | 6 +- libavcodec/s302m.c | 2 +- libavcodec/sgidec.c | 32 +- libavcodec/shorten.c | 2 +- libavcodec/sipr.c | 2 +- libavcodec/smacker.c | 17 +- libavcodec/smc.c | 15 +- libavcodec/sunrast.c | 35 +- libavcodec/svq1dec.c | 34 +- libavcodec/svq1enc.c | 11 +- libavcodec/svq3.c | 114 +++--- libavcodec/takdec.c | 2 +- libavcodec/targa.c | 30 +- libavcodec/thread.h | 20 +- libavcodec/tiertexseqv.c | 14 +- libavcodec/tiff.c | 27 +- libavcodec/tmv.c | 39 +- libavcodec/truemotion1.c | 17 +- libavcodec/truemotion2.c | 13 +- libavcodec/truespeech.c | 2 +- libavcodec/tscc.c | 18 +- libavcodec/tscc2.c | 17 +- libavcodec/tta.c | 2 +- libavcodec/twinvq.c | 2 +- libavcodec/txd.c | 35 +- libavcodec/ulti.c | 15 +- libavcodec/utils.c | 637 ++++++++++++++++++++------------ libavcodec/utvideo.h | 1 - libavcodec/utvideodec.c | 46 +-- libavcodec/v210dec.c | 24 +- libavcodec/v210x.c | 22 +- libavcodec/v410dec.c | 28 +- libavcodec/vaapi_h264.c | 10 +- libavcodec/vb.c | 18 +- libavcodec/vble.c | 35 +- libavcodec/vc1dec.c | 362 +++++++++--------- libavcodec/vcr1.c | 39 +- libavcodec/vdpau.c | 12 +- libavcodec/vdpau_h264.c | 12 +- libavcodec/version.h | 3 + libavcodec/vmdav.c | 38 +- libavcodec/vmnc.c | 15 +- libavcodec/vorbisdec.c | 2 +- libavcodec/vp3.c | 172 +++++---- libavcodec/vp5.c | 12 +- libavcodec/vp56.c | 97 ++--- libavcodec/vp56.h | 6 +- libavcodec/vp56data.h | 2 - libavcodec/vp6.c | 17 +- libavcodec/vp8.c | 203 +++++----- libavcodec/vp8.h | 27 +- libavcodec/vqavideo.c | 43 +-- libavcodec/wavpack.c | 2 +- libavcodec/wmadec.c | 2 +- libavcodec/wmalosslessdec.c | 2 +- libavcodec/wmaprodec.c | 2 +- libavcodec/wmavoice.c | 2 +- libavcodec/wmv2dec.c | 12 +- libavcodec/wnv1.c | 22 +- libavcodec/ws-snd1.c | 2 +- libavcodec/xan.c | 49 ++- libavcodec/xl.c | 41 +- libavcodec/xwddec.c | 30 +- libavcodec/xxan.c | 14 +- libavcodec/yop.c | 59 ++- libavcodec/zerocodec.c | 36 +- libavcodec/zmbv.c | 32 +- 239 files changed, 3904 insertions(+), 4335 deletions(-) diff --git a/doc/multithreading.txt b/doc/multithreading.txt index b72bc16079..9b27b108c6 100644 --- a/doc/multithreading.txt +++ b/doc/multithreading.txt @@ -57,6 +57,11 @@ which re-allocates them for other threads. Add CODEC_CAP_FRAME_THREADS to the codec capabilities. There will be very little speed gain at this point but it should work. +If there are inter-frame dependencies, so the codec calls +ff_thread_report/await_progress(), set AVCodecInternal.allocate_progress. The +frames must then be freed with ff_thread_release_buffer(). +Otherwise leave it at zero and decode directly into the user-supplied frames. + Call ff_thread_report_progress() after some part of the current picture has decoded. A good place to put this is where draw_horiz_band() is called - add this if it isn't called anywhere, as it's useful too and the implementation is trivial when you're diff --git a/libavcodec/4xm.c b/libavcodec/4xm.c index 82f8417f0e..e34fa1ddc6 100644 --- a/libavcodec/4xm.c +++ b/libavcodec/4xm.c @@ -24,6 +24,7 @@ * 4XM codec. */ +#include "libavutil/frame.h" #include "libavutil/intreadwrite.h" #include "avcodec.h" #include "bytestream.h" @@ -131,7 +132,7 @@ typedef struct CFrameBuffer { typedef struct FourXContext { AVCodecContext *avctx; DSPContext dsp; - AVFrame *current_picture, *last_picture; + AVFrame *last_picture; GetBitContext pre_gb; ///< ac/dc prefix GetBitContext gb; GetByteContext g; @@ -256,15 +257,15 @@ static av_cold void init_vlcs(FourXContext *f) } } -static void init_mv(FourXContext *f) +static void init_mv(FourXContext *f, int linesize) { int i; for (i = 0; i < 256; i++) { if (f->version > 1) - f->mv[i] = mv[i][0] + mv[i][1] * f->current_picture->linesize[0] / 2; + f->mv[i] = mv[i][0] + mv[i][1] * linesize / 2; else - f->mv[i] = (i & 15) - 8 + ((i >> 4) - 8) * f->current_picture->linesize[0] / 2; + f->mv[i] = (i & 15) - 8 + ((i >> 4) - 8) * linesize / 2; } } @@ -385,14 +386,15 @@ static void decode_p_block(FourXContext *f, uint16_t *dst, uint16_t *src, } } -static int decode_p_frame(FourXContext *f, const uint8_t *buf, int length) +static int decode_p_frame(FourXContext *f, AVFrame *frame, + const uint8_t *buf, int length) { int x, y; const int width = f->avctx->width; const int height = f->avctx->height; uint16_t *src = (uint16_t *)f->last_picture->data[0]; - uint16_t *dst = (uint16_t *)f->current_picture->data[0]; - const int stride = f->current_picture->linesize[0] >> 1; + uint16_t *dst = (uint16_t *)frame->data[0]; + const int stride = frame->linesize[0] >> 1; unsigned int bitstream_size, bytestream_size, wordstream_size, extra, bytestream_offset, wordstream_offset; @@ -435,7 +437,7 @@ static int decode_p_frame(FourXContext *f, const uint8_t *buf, int length) bytestream2_init(&f->g, buf + bytestream_offset, length - bytestream_offset); - init_mv(f); + init_mv(f, frame->linesize[0]); for (y = 0; y < height; y += 8) { for (x = 0; x < width; x += 8) @@ -494,12 +496,12 @@ static int decode_i_block(FourXContext *f, int16_t *block) return 0; } -static inline void idct_put(FourXContext *f, int x, int y) +static inline void idct_put(FourXContext *f, AVFrame *frame, int x, int y) { int16_t (*block)[64] = f->block; - int stride = f->current_picture->linesize[0] >> 1; + int stride = frame->linesize[0] >> 1; int i; - uint16_t *dst = ((uint16_t*)f->current_picture->data[0]) + y * stride + x; + uint16_t *dst = ((uint16_t*)frame->data[0]) + y * stride + x; for (i = 0; i < 4; i++) { block[i][0] += 0x80 * 8 * 8; @@ -647,14 +649,14 @@ static int mix(int c0, int c1) return red / 3 * 1024 + green / 3 * 32 + blue / 3; } -static int decode_i2_frame(FourXContext *f, const uint8_t *buf, int length) +static int decode_i2_frame(FourXContext *f, AVFrame *frame, const uint8_t *buf, int length) { int x, y, x2, y2; const int width = f->avctx->width; const int height = f->avctx->height; const int mbs = (FFALIGN(width, 16) >> 4) * (FFALIGN(height, 16) >> 4); - uint16_t *dst = (uint16_t*)f->current_picture->data[0]; - const int stride = f->current_picture->linesize[0]>>1; + uint16_t *dst = (uint16_t*)frame->data[0]; + const int stride = frame->linesize[0]>>1; GetByteContext g3; if (length < mbs * 8) { @@ -693,7 +695,7 @@ static int decode_i2_frame(FourXContext *f, const uint8_t *buf, int length) return 0; } -static int decode_i_frame(FourXContext *f, const uint8_t *buf, int length) +static int decode_i_frame(FourXContext *f, AVFrame *frame, const uint8_t *buf, int length) { int x, y, ret; const int width = f->avctx->width; @@ -747,7 +749,7 @@ static int decode_i_frame(FourXContext *f, const uint8_t *buf, int length) if ((ret = decode_i_mb(f)) < 0) return ret; - idct_put(f, x, y); + idct_put(f, frame, x, y); } } @@ -764,7 +766,6 @@ static int decode_frame(AVCodecContext *avctx, void *data, int buf_size = avpkt->size; FourXContext *const f = avctx->priv_data; AVFrame *picture = data; - AVFrame *p; int i, frame_4cc, frame_size, ret; frame_4cc = AV_RL32(buf); @@ -825,43 +826,34 @@ static int decode_frame(AVCodecContext *avctx, void *data, frame_size = buf_size - 12; } - FFSWAP(AVFrame*, f->current_picture, f->last_picture); - - p = f->current_picture; - avctx->coded_frame = p; - // alternatively we would have to use our own buffer management avctx->flags |= CODEC_FLAG_EMU_EDGE; - if (p->data[0]) - avctx->release_buffer(avctx, p); - - p->reference = 1; - if ((ret = ff_get_buffer(avctx, p)) < 0) { + if ((ret = ff_get_buffer(avctx, picture, AV_GET_BUFFER_FLAG_REF)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } if (frame_4cc == AV_RL32("ifr2")) { - p->pict_type = AV_PICTURE_TYPE_I; - if ((ret = decode_i2_frame(f, buf - 4, frame_size + 4)) < 0) + picture->pict_type = AV_PICTURE_TYPE_I; + if ((ret = decode_i2_frame(f, picture, buf - 4, frame_size + 4)) < 0) return ret; } else if (frame_4cc == AV_RL32("ifrm")) { - p->pict_type = AV_PICTURE_TYPE_I; - if ((ret = decode_i_frame(f, buf, frame_size)) < 0) + picture->pict_type = AV_PICTURE_TYPE_I; + if ((ret = decode_i_frame(f, picture, buf, frame_size)) < 0) return ret; } else if (frame_4cc == AV_RL32("pfrm") || frame_4cc == AV_RL32("pfr2")) { if (!f->last_picture->data[0]) { - f->last_picture->reference = 1; - if ((ret = ff_get_buffer(avctx, f->last_picture)) < 0) { + if ((ret = ff_get_buffer(avctx, f->last_picture, + AV_GET_BUFFER_FLAG_REF)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } memset(f->last_picture->data[0], 0, avctx->height * FFABS(f->last_picture->linesize[0])); } - p->pict_type = AV_PICTURE_TYPE_P; - if ((ret = decode_p_frame(f, buf, frame_size)) < 0) + picture->pict_type = AV_PICTURE_TYPE_P; + if ((ret = decode_p_frame(f, picture, buf, frame_size)) < 0) return ret; } else if (frame_4cc == AV_RL32("snd_")) { av_log(avctx, AV_LOG_ERROR, "ignoring snd_ chunk length:%d\n", @@ -871,9 +863,11 @@ static int decode_frame(AVCodecContext *avctx, void *data, buf_size); } - p->key_frame = p->pict_type == AV_PICTURE_TYPE_I; + picture->key_frame = picture->pict_type == AV_PICTURE_TYPE_I; - *picture = *p; + av_frame_unref(f->last_picture); + if ((ret = av_frame_ref(f->last_picture, picture)) < 0) + return ret; *got_frame = 1; emms_c(); @@ -900,13 +894,9 @@ static av_cold int decode_init(AVCodecContext *avctx) else avctx->pix_fmt = AV_PIX_FMT_BGR555; - f->current_picture = avcodec_alloc_frame(); - f->last_picture = avcodec_alloc_frame(); - if (!f->current_picture || !f->last_picture) { - avcodec_free_frame(&f->current_picture); - avcodec_free_frame(&f->last_picture); + f->last_picture = av_frame_alloc(); + if (!f->last_picture) return AVERROR(ENOMEM); - } return 0; } @@ -924,12 +914,7 @@ static av_cold int decode_end(AVCodecContext *avctx) f->cfrm[i].allocated_size = 0; } ff_free_vlc(&f->pre_vlc); - if (f->current_picture->data[0]) - avctx->release_buffer(avctx, f->current_picture); - if (f->last_picture->data[0]) - avctx->release_buffer(avctx, f->last_picture); - avcodec_free_frame(&f->current_picture); - avcodec_free_frame(&f->last_picture); + av_frame_free(&f->last_picture); return 0; } diff --git a/libavcodec/8bps.c b/libavcodec/8bps.c index ceed13f5b8..fcb7b2bfcd 100644 --- a/libavcodec/8bps.c +++ b/libavcodec/8bps.c @@ -46,7 +46,6 @@ static const enum AVPixelFormat pixfmt_rgb24[] = { typedef struct EightBpsContext { AVCodecContext *avctx; - AVFrame pic; unsigned char planes; unsigned char planemap[4]; @@ -57,6 +56,7 @@ typedef struct EightBpsContext { static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { + AVFrame *frame = data; const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; EightBpsContext * const c = avctx->priv_data; @@ -71,12 +71,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, unsigned char *planemap = c->planemap; int ret; - if (c->pic.data[0]) - avctx->release_buffer(avctx, &c->pic); - - c->pic.reference = 0; - c->pic.buffer_hints = FF_BUFFER_HINTS_VALID; - if ((ret = ff_get_buffer(avctx, &c->pic)) < 0) { + if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } @@ -96,8 +91,8 @@ static int decode_frame(AVCodecContext *avctx, void *data, /* Decode a plane */ for (row = 0; row < height; row++) { - pixptr = c->pic.data[0] + row * c->pic.linesize[0] + planemap[p]; - pixptr_end = pixptr + c->pic.linesize[0]; + pixptr = frame->data[0] + row * frame->linesize[0] + planemap[p]; + pixptr_end = pixptr + frame->linesize[0]; dlen = av_be2ne16(*(const unsigned short *)(lp + row * 2)); /* Decode a row of this plane */ while (dlen > 0) { @@ -134,15 +129,14 @@ static int decode_frame(AVCodecContext *avctx, void *data, AV_PKT_DATA_PALETTE, NULL); if (pal) { - c->pic.palette_has_changed = 1; + frame->palette_has_changed = 1; memcpy(c->pal, pal, AVPALETTE_SIZE); } - memcpy (c->pic.data[1], c->pal, AVPALETTE_SIZE); + memcpy (frame->data[1], c->pal, AVPALETTE_SIZE); } *got_frame = 1; - *(AVFrame*)data = c->pic; /* always report that the buffer was completely consumed */ return buf_size; @@ -153,7 +147,6 @@ static av_cold int decode_init(AVCodecContext *avctx) EightBpsContext * const c = avctx->priv_data; c->avctx = avctx; - c->pic.data[0] = NULL; switch (avctx->bits_per_coded_sample) { case 8: @@ -192,23 +185,12 @@ static av_cold int decode_init(AVCodecContext *avctx) return 0; } -static av_cold int decode_end(AVCodecContext *avctx) -{ - EightBpsContext * const c = avctx->priv_data; - - if (c->pic.data[0]) - avctx->release_buffer(avctx, &c->pic); - - return 0; -} - AVCodec ff_eightbps_decoder = { .name = "8bps", .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_8BPS, .priv_data_size = sizeof(EightBpsContext), .init = decode_init, - .close = decode_end, .decode = decode_frame, .capabilities = CODEC_CAP_DR1, .long_name = NULL_IF_CONFIG_SMALL("QuickTime 8BPS video"), diff --git a/libavcodec/8svx.c b/libavcodec/8svx.c index 4f2a8971e7..94eb319d3d 100644 --- a/libavcodec/8svx.c +++ b/libavcodec/8svx.c @@ -137,7 +137,7 @@ static int eightsvx_decode_frame(AVCodecContext *avctx, void *data, /* get output buffer */ frame->nb_samples = buf_size * (is_compr + 1); - if ((ret = ff_get_buffer(avctx, frame)) < 0) { + if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } diff --git a/libavcodec/aacdec.c b/libavcodec/aacdec.c index e044f9ab65..43a6029ef4 100644 --- a/libavcodec/aacdec.c +++ b/libavcodec/aacdec.c @@ -179,8 +179,9 @@ static int frame_configure_elements(AVCodecContext *avctx) } /* get output buffer */ + av_frame_unref(ac->frame); ac->frame->nb_samples = 2048; - if ((ret = ff_get_buffer(avctx, ac->frame)) < 0) { + if ((ret = ff_get_buffer(avctx, ac->frame, 0)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } diff --git a/libavcodec/aasc.c b/libavcodec/aasc.c index 5fcdfc0194..bce27c0e10 100644 --- a/libavcodec/aasc.c +++ b/libavcodec/aasc.c @@ -29,12 +29,13 @@ #include #include "avcodec.h" +#include "internal.h" #include "msrledec.h" typedef struct AascContext { AVCodecContext *avctx; GetByteContext gb; - AVFrame frame; + AVFrame *frame; } AascContext; static av_cold int aasc_decode_init(AVCodecContext *avctx) @@ -45,6 +46,10 @@ static av_cold int aasc_decode_init(AVCodecContext *avctx) avctx->pix_fmt = AV_PIX_FMT_BGR24; + s->frame = av_frame_alloc(); + if (!s->frame) + return AVERROR(ENOMEM); + return 0; } @@ -57,9 +62,7 @@ static int aasc_decode_frame(AVCodecContext *avctx, AascContext *s = avctx->priv_data; int compr, i, stride, ret; - s->frame.reference = 1; - s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE; - if ((ret = avctx->reget_buffer(avctx, &s->frame)) < 0) { + if ((ret = ff_reget_buffer(avctx, s->frame)) < 0) { av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); return ret; } @@ -71,13 +74,13 @@ static int aasc_decode_frame(AVCodecContext *avctx, case 0: stride = (avctx->width * 3 + 3) & ~3; for (i = avctx->height - 1; i >= 0; i--) { - memcpy(s->frame.data[0] + i * s->frame.linesize[0], buf, avctx->width * 3); + memcpy(s->frame->data[0] + i * s->frame->linesize[0], buf, avctx->width * 3); buf += stride; } break; case 1: bytestream2_init(&s->gb, buf, buf_size); - ff_msrle_decode(avctx, (AVPicture*)&s->frame, 8, &s->gb); + ff_msrle_decode(avctx, (AVPicture*)s->frame, 8, &s->gb); break; default: av_log(avctx, AV_LOG_ERROR, "Unknown compression type %d\n", compr); @@ -85,7 +88,8 @@ static int aasc_decode_frame(AVCodecContext *avctx, } *got_frame = 1; - *(AVFrame*)data = s->frame; + if ((ret = av_frame_ref(data, s->frame)) < 0) + return ret; /* report that the buffer was completely consumed */ return buf_size; @@ -95,9 +99,7 @@ static av_cold int aasc_decode_end(AVCodecContext *avctx) { AascContext *s = avctx->priv_data; - /* release the last frame */ - if (s->frame.data[0]) - avctx->release_buffer(avctx, &s->frame); + av_frame_free(&s->frame); return 0; } diff --git a/libavcodec/ac3dec.c b/libavcodec/ac3dec.c index f8f058477f..407940d19d 100644 --- a/libavcodec/ac3dec.c +++ b/libavcodec/ac3dec.c @@ -1371,7 +1371,7 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data, /* get output buffer */ frame->nb_samples = s->num_blocks * 256; - if ((ret = ff_get_buffer(avctx, frame)) < 0) { + if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } diff --git a/libavcodec/adpcm.c b/libavcodec/adpcm.c index becb480c40..3e93bee20e 100644 --- a/libavcodec/adpcm.c +++ b/libavcodec/adpcm.c @@ -609,7 +609,7 @@ static int adpcm_decode_frame(AVCodecContext *avctx, void *data, /* get output buffer */ frame->nb_samples = nb_samples; - if ((ret = ff_get_buffer(avctx, frame)) < 0) { + if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } diff --git a/libavcodec/adxdec.c b/libavcodec/adxdec.c index ea40993124..52216867cc 100644 --- a/libavcodec/adxdec.c +++ b/libavcodec/adxdec.c @@ -141,7 +141,7 @@ static int adx_decode_frame(AVCodecContext *avctx, void *data, /* get output buffer */ frame->nb_samples = num_blocks * BLOCK_SAMPLES; - if ((ret = ff_get_buffer(avctx, frame)) < 0) { + if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } diff --git a/libavcodec/alac.c b/libavcodec/alac.c index 0c5bdd3e45..ddf78d9108 100644 --- a/libavcodec/alac.c +++ b/libavcodec/alac.c @@ -283,7 +283,7 @@ static int decode_element(AVCodecContext *avctx, AVFrame *frame, int ch_index, if (!alac->nb_samples) { /* get output buffer */ frame->nb_samples = output_samples; - if ((ret = ff_get_buffer(avctx, frame)) < 0) { + if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } diff --git a/libavcodec/alsdec.c b/libavcodec/alsdec.c index 622522aaa6..f87c94425b 100644 --- a/libavcodec/alsdec.c +++ b/libavcodec/alsdec.c @@ -1462,7 +1462,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame_ptr, /* get output buffer */ frame->nb_samples = ctx->cur_frame_length; - if ((ret = ff_get_buffer(avctx, frame)) < 0) { + if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } diff --git a/libavcodec/amrnbdec.c b/libavcodec/amrnbdec.c index 237d47b7cb..20c1896ec3 100644 --- a/libavcodec/amrnbdec.c +++ b/libavcodec/amrnbdec.c @@ -945,7 +945,7 @@ static int amrnb_decode_frame(AVCodecContext *avctx, void *data, /* get output buffer */ frame->nb_samples = AMR_BLOCK_SIZE; - if ((ret = ff_get_buffer(avctx, frame)) < 0) { + if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } diff --git a/libavcodec/amrwbdec.c b/libavcodec/amrwbdec.c index cf137e046a..354b039025 100644 --- a/libavcodec/amrwbdec.c +++ b/libavcodec/amrwbdec.c @@ -1092,7 +1092,7 @@ static int amrwb_decode_frame(AVCodecContext *avctx, void *data, /* get output buffer */ frame->nb_samples = 4 * AMRWB_SFR_SIZE_16k; - if ((ret = ff_get_buffer(avctx, frame)) < 0) { + if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } diff --git a/libavcodec/anm.c b/libavcodec/anm.c index af148a6fd0..9f1cc397f9 100644 --- a/libavcodec/anm.c +++ b/libavcodec/anm.c @@ -26,9 +26,10 @@ #include "avcodec.h" #include "bytestream.h" +#include "internal.h" typedef struct AnmContext { - AVFrame frame; + AVFrame *frame; int palette[AVPALETTE_COUNT]; GetByteContext gb; int x; ///< x coordinate position @@ -41,7 +42,10 @@ static av_cold int decode_init(AVCodecContext *avctx) avctx->pix_fmt = AV_PIX_FMT_PAL8; - s->frame.reference = 1; + s->frame = av_frame_alloc(); + if (!s->frame) + return AVERROR(ENOMEM); + bytestream2_init(&s->gb, avctx->extradata, avctx->extradata_size); if (bytestream2_get_bytes_left(&s->gb) < 16 * 8 + 4 * 256) return AVERROR_INVALIDDATA; @@ -113,12 +117,12 @@ static int decode_frame(AVCodecContext *avctx, uint8_t *dst, *dst_end; int count, ret; - if ((ret = avctx->reget_buffer(avctx, &s->frame)) < 0){ + if ((ret = ff_reget_buffer(avctx, s->frame)) < 0){ av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } - dst = s->frame.data[0]; - dst_end = s->frame.data[0] + s->frame.linesize[0]*avctx->height; + dst = s->frame->data[0]; + dst_end = s->frame->data[0] + s->frame->linesize[0]*avctx->height; bytestream2_init(&s->gb, avpkt->data, buf_size); @@ -136,7 +140,7 @@ static int decode_frame(AVCodecContext *avctx, do { /* if statements are ordered by probability */ #define OP(gb, pixel, count) \ - op(&dst, dst_end, (gb), (pixel), (count), &s->x, avctx->width, s->frame.linesize[0]) + op(&dst, dst_end, (gb), (pixel), (count), &s->x, avctx->width, s->frame->linesize[0]) int type = bytestream2_get_byte(&s->gb); count = type & 0x7F; @@ -168,18 +172,20 @@ static int decode_frame(AVCodecContext *avctx, } } while (bytestream2_get_bytes_left(&s->gb) > 0); - memcpy(s->frame.data[1], s->palette, AVPALETTE_SIZE); + memcpy(s->frame->data[1], s->palette, AVPALETTE_SIZE); *got_frame = 1; - *(AVFrame*)data = s->frame; + if ((ret = av_frame_ref(data, s->frame)) < 0) + return ret; + return buf_size; } static av_cold int decode_end(AVCodecContext *avctx) { AnmContext *s = avctx->priv_data; - if (s->frame.data[0]) - avctx->release_buffer(avctx, &s->frame); + + av_frame_free(&s->frame); return 0; } diff --git a/libavcodec/ansi.c b/libavcodec/ansi.c index 0b2e93d74b..b99826b3a5 100644 --- a/libavcodec/ansi.c +++ b/libavcodec/ansi.c @@ -25,6 +25,7 @@ */ #include "libavutil/common.h" +#include "libavutil/frame.h" #include "libavutil/lfg.h" #include "avcodec.h" #include "cga_data.h" @@ -49,7 +50,7 @@ static const uint8_t ansi_to_cga[16] = { }; typedef struct { - AVFrame frame; + AVFrame *frame; int x; /**< x cursor position (pixels) */ int y; /**< y cursor position (pixels) */ int sx; /**< saved x cursor position (pixels) */ @@ -77,6 +78,10 @@ static av_cold int decode_init(AVCodecContext *avctx) AnsiContext *s = avctx->priv_data; avctx->pix_fmt = AV_PIX_FMT_PAL8; + s->frame = av_frame_alloc(); + if (!s->frame) + return AVERROR(ENOMEM); + /* defaults */ s->font = ff_vga16_font; s->font_height = 16; @@ -101,11 +106,11 @@ static void hscroll(AVCodecContext *avctx) i = 0; for (; i < avctx->height - s->font_height; i++) - memcpy(s->frame.data[0] + i * s->frame.linesize[0], - s->frame.data[0] + (i + s->font_height) * s->frame.linesize[0], + memcpy(s->frame->data[0] + i * s->frame->linesize[0], + s->frame->data[0] + (i + s->font_height) * s->frame->linesize[0], avctx->width); for (; i < avctx->height; i++) - memset(s->frame.data[0] + i * s->frame.linesize[0], + memset(s->frame->data[0] + i * s->frame->linesize[0], DEFAULT_BG_COLOR, avctx->width); } @@ -114,7 +119,7 @@ static void erase_line(AVCodecContext * avctx, int xoffset, int xlength) AnsiContext *s = avctx->priv_data; int i; for (i = 0; i < s->font_height; i++) - memset(s->frame.data[0] + (s->y + i)*s->frame.linesize[0] + xoffset, + memset(s->frame->data[0] + (s->y + i)*s->frame->linesize[0] + xoffset, DEFAULT_BG_COLOR, xlength); } @@ -123,7 +128,7 @@ static void erase_screen(AVCodecContext *avctx) AnsiContext *s = avctx->priv_data; int i; for (i = 0; i < avctx->height; i++) - memset(s->frame.data[0] + i * s->frame.linesize[0], DEFAULT_BG_COLOR, avctx->width); + memset(s->frame->data[0] + i * s->frame->linesize[0], DEFAULT_BG_COLOR, avctx->width); s->x = s->y = 0; } @@ -144,8 +149,8 @@ static void draw_char(AVCodecContext *avctx, int c) FFSWAP(int, fg, bg); if ((s->attributes & ATTR_CONCEALED)) fg = bg; - ff_draw_pc_font(s->frame.data[0] + s->y * s->frame.linesize[0] + s->x, - s->frame.linesize[0], s->font, s->font_height, c, fg, bg); + ff_draw_pc_font(s->frame->data[0] + s->y * s->frame->linesize[0] + s->x, + s->frame->linesize[0], s->font, s->font_height, c, fg, bg); s->x += FONT_WIDTH; if (s->x >= avctx->width) { s->x = 0; @@ -220,17 +225,16 @@ static int execute_code(AVCodecContext * avctx, int c) av_log_ask_for_sample(avctx, "unsupported screen mode\n"); } if (width != avctx->width || height != avctx->height) { - if (s->frame.data[0]) - avctx->release_buffer(avctx, &s->frame); + av_frame_unref(s->frame); avcodec_set_dimensions(avctx, width, height); - ret = ff_get_buffer(avctx, &s->frame); + ret = ff_get_buffer(avctx, s->frame, AV_GET_BUFFER_FLAG_REF); if (ret < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } - s->frame.pict_type = AV_PICTURE_TYPE_I; - s->frame.palette_has_changed = 1; - memcpy(s->frame.data[1], ff_cga_palette, 16 * 4); + s->frame->pict_type = AV_PICTURE_TYPE_I; + s->frame->palette_has_changed = 1; + memcpy(s->frame->data[1], ff_cga_palette, 16 * 4); erase_screen(avctx); } else if (c == 'l') { erase_screen(avctx); @@ -241,13 +245,13 @@ static int execute_code(AVCodecContext * avctx, int c) case 0: erase_line(avctx, s->x, avctx->width - s->x); if (s->y < avctx->height - s->font_height) - memset(s->frame.data[0] + (s->y + s->font_height)*s->frame.linesize[0], - DEFAULT_BG_COLOR, (avctx->height - s->y - s->font_height)*s->frame.linesize[0]); + memset(s->frame->data[0] + (s->y + s->font_height)*s->frame->linesize[0], + DEFAULT_BG_COLOR, (avctx->height - s->y - s->font_height)*s->frame->linesize[0]); break; case 1: erase_line(avctx, 0, s->x); if (s->y > 0) - memset(s->frame.data[0], DEFAULT_BG_COLOR, s->y * s->frame.linesize[0]); + memset(s->frame->data[0], DEFAULT_BG_COLOR, s->y * s->frame->linesize[0]); break; case 2: erase_screen(avctx); @@ -320,19 +324,19 @@ static int decode_frame(AVCodecContext *avctx, const uint8_t *buf_end = buf+buf_size; int ret, i, count; - ret = avctx->reget_buffer(avctx, &s->frame); + ret = ff_reget_buffer(avctx, s->frame); if (ret < 0){ av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } if (!avctx->frame_number) { - memset(s->frame.data[0], 0, avctx->height * FFABS(s->frame.linesize[0])); - memset(s->frame.data[1], 0, AVPALETTE_SIZE); + memset(s->frame->data[0], 0, avctx->height * FFABS(s->frame->linesize[0])); + memset(s->frame->data[1], 0, AVPALETTE_SIZE); } - s->frame.pict_type = AV_PICTURE_TYPE_I; - s->frame.palette_has_changed = 1; - memcpy(s->frame.data[1], ff_cga_palette, 16 * 4); + s->frame->pict_type = AV_PICTURE_TYPE_I; + s->frame->palette_has_changed = 1; + memcpy(s->frame->data[1], ff_cga_palette, 16 * 4); while(buf < buf_end) { switch(s->state) { @@ -416,15 +420,16 @@ static int decode_frame(AVCodecContext *avctx, } *got_frame = 1; - *(AVFrame*)data = s->frame; + if ((ret = av_frame_ref(data, s->frame)) < 0) + return ret; return buf_size; } static av_cold int decode_close(AVCodecContext *avctx) { AnsiContext *s = avctx->priv_data; - if (s->frame.data[0]) - avctx->release_buffer(avctx, &s->frame); + + av_frame_free(&s->frame); return 0; } diff --git a/libavcodec/apedec.c b/libavcodec/apedec.c index f3635836d0..60227a04e9 100644 --- a/libavcodec/apedec.c +++ b/libavcodec/apedec.c @@ -907,7 +907,7 @@ static int ape_decode_frame(AVCodecContext *avctx, void *data, /* get output buffer */ frame->nb_samples = blockstodecode; - if ((ret = ff_get_buffer(avctx, frame)) < 0) { + if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } diff --git a/libavcodec/asvdec.c b/libavcodec/asvdec.c index a3adde9356..a1246877a7 100644 --- a/libavcodec/asvdec.c +++ b/libavcodec/asvdec.c @@ -183,14 +183,14 @@ static inline int decode_mb(ASV1Context *a, int16_t block[6][64]) return 0; } -static inline void idct_put(ASV1Context *a, int mb_x, int mb_y) +static inline void idct_put(ASV1Context *a, AVFrame *frame, int mb_x, int mb_y) { int16_t (*block)[64] = a->block; - int linesize = a->picture.linesize[0]; + int linesize = frame->linesize[0]; - uint8_t *dest_y = a->picture.data[0] + (mb_y * 16* linesize ) + mb_x * 16; - uint8_t *dest_cb = a->picture.data[1] + (mb_y * 8 * a->picture.linesize[1]) + mb_x * 8; - uint8_t *dest_cr = a->picture.data[2] + (mb_y * 8 * a->picture.linesize[2]) + mb_x * 8; + uint8_t *dest_y = frame->data[0] + (mb_y * 16* linesize ) + mb_x * 16; + uint8_t *dest_cb = frame->data[1] + (mb_y * 8 * frame->linesize[1]) + mb_x * 8; + uint8_t *dest_cr = frame->data[2] + (mb_y * 8 * frame->linesize[2]) + mb_x * 8; a->dsp.idct_put(dest_y , linesize, block[0]); a->dsp.idct_put(dest_y + 8, linesize, block[1]); @@ -198,8 +198,8 @@ static inline void idct_put(ASV1Context *a, int mb_x, int mb_y) a->dsp.idct_put(dest_y + 8*linesize + 8, linesize, block[3]); if (!(a->avctx->flags&CODEC_FLAG_GRAY)) { - a->dsp.idct_put(dest_cb, a->picture.linesize[1], block[4]); - a->dsp.idct_put(dest_cr, a->picture.linesize[2], block[5]); + a->dsp.idct_put(dest_cb, frame->linesize[1], block[4]); + a->dsp.idct_put(dest_cr, frame->linesize[2], block[5]); } } @@ -210,15 +210,10 @@ static int decode_frame(AVCodecContext *avctx, ASV1Context * const a = avctx->priv_data; const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; - AVFrame *picture = data; - AVFrame * const p = &a->picture; + AVFrame * const p = data; int mb_x, mb_y, ret; - if (p->data[0]) - avctx->release_buffer(avctx, p); - - p->reference = 0; - if ((ret = ff_get_buffer(avctx, p)) < 0) { + if ((ret = ff_get_buffer(avctx, p, 0)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } @@ -245,7 +240,7 @@ static int decode_frame(AVCodecContext *avctx, if ((ret = decode_mb(a, a->block)) < 0) return ret; - idct_put(a, mb_x, mb_y); + idct_put(a, p, mb_x, mb_y); } } @@ -255,7 +250,7 @@ static int decode_frame(AVCodecContext *avctx, if ((ret = decode_mb(a, a->block)) < 0) return ret; - idct_put(a, mb_x, mb_y); + idct_put(a, p, mb_x, mb_y); } } @@ -265,11 +260,10 @@ static int decode_frame(AVCodecContext *avctx, if ((ret = decode_mb(a, a->block)) < 0) return ret; - idct_put(a, mb_x, mb_y); + idct_put(a, p, mb_x, mb_y); } } - *picture = a->picture; *got_frame = 1; emms_c(); @@ -280,7 +274,6 @@ static int decode_frame(AVCodecContext *avctx, static av_cold int decode_init(AVCodecContext *avctx) { ASV1Context * const a = avctx->priv_data; - AVFrame *p = &a->picture; const int scale = avctx->codec_id == AV_CODEC_ID_ASV1 ? 1 : 2; int i; @@ -304,11 +297,6 @@ static av_cold int decode_init(AVCodecContext *avctx) a->intra_matrix[i] = 64 * scale * ff_mpeg1_default_intra_matrix[index] / a->inv_qscale; } - p->qstride = a->mb_width; - p->qscale_table = av_malloc(p->qstride * a->mb_height); - p->quality = (32 * scale + a->inv_qscale / 2) / a->inv_qscale; - memset(p->qscale_table, p->quality, p->qstride * a->mb_height); - return 0; } @@ -317,12 +305,8 @@ static av_cold int decode_end(AVCodecContext *avctx) ASV1Context * const a = avctx->priv_data; av_freep(&a->bitstream_buffer); - av_freep(&a->picture.qscale_table); a->bitstream_buffer_size = 0; - if (a->picture.data[0]) - avctx->release_buffer(avctx, &a->picture); - return 0; } diff --git a/libavcodec/atrac1.c b/libavcodec/atrac1.c index 9c265464fe..c829898ddb 100644 --- a/libavcodec/atrac1.c +++ b/libavcodec/atrac1.c @@ -287,7 +287,7 @@ static int atrac1_decode_frame(AVCodecContext *avctx, void *data, /* get output buffer */ frame->nb_samples = AT1_SU_SAMPLES; - if ((ret = ff_get_buffer(avctx, frame)) < 0) { + if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } diff --git a/libavcodec/atrac3.c b/libavcodec/atrac3.c index 0474268f46..6b4165780c 100644 --- a/libavcodec/atrac3.c +++ b/libavcodec/atrac3.c @@ -812,7 +812,7 @@ static int atrac3_decode_frame(AVCodecContext *avctx, void *data, /* get output buffer */ frame->nb_samples = SAMPLES_PER_FRAME; - if ((ret = ff_get_buffer(avctx, frame)) < 0) { + if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } diff --git a/libavcodec/aura.c b/libavcodec/aura.c index 7256dc8274..b51aedeccf 100644 --- a/libavcodec/aura.c +++ b/libavcodec/aura.c @@ -27,16 +27,8 @@ #include "internal.h" #include "libavutil/internal.h" -typedef struct AuraDecodeContext { - AVCodecContext *avctx; - AVFrame frame; -} AuraDecodeContext; - static av_cold int aura_decode_init(AVCodecContext *avctx) { - AuraDecodeContext *s = avctx->priv_data; - - s->avctx = avctx; /* width needs to be divisible by 4 for this codec to work */ if (avctx->width & 0x3) return AVERROR(EINVAL); @@ -49,7 +41,7 @@ static int aura_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *pkt) { - AuraDecodeContext *s = avctx->priv_data; + AVFrame *frame = data; uint8_t *Y, *U, *V; uint8_t val; int x, y, ret; @@ -67,19 +59,14 @@ static int aura_decode_frame(AVCodecContext *avctx, /* pixel data starts 48 bytes in, after 3x16-byte tables */ buf += 48; - if (s->frame.data[0]) - avctx->release_buffer(avctx, &s->frame); - - s->frame.buffer_hints = FF_BUFFER_HINTS_VALID; - s->frame.reference = 0; - if ((ret = ff_get_buffer(avctx, &s->frame)) < 0) { + if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } - Y = s->frame.data[0]; - U = s->frame.data[1]; - V = s->frame.data[2]; + Y = frame->data[0]; + U = frame->data[1]; + V = frame->data[2]; /* iterate through each line in the height */ for (y = 0; y < avctx->height; y++) { @@ -102,34 +89,21 @@ static int aura_decode_frame(AVCodecContext *avctx, Y[1] = Y[ 0] + delta_table[val & 0xF]; Y += 2; U++; V++; } - Y += s->frame.linesize[0] - avctx->width; - U += s->frame.linesize[1] - (avctx->width >> 1); - V += s->frame.linesize[2] - (avctx->width >> 1); + Y += frame->linesize[0] - avctx->width; + U += frame->linesize[1] - (avctx->width >> 1); + V += frame->linesize[2] - (avctx->width >> 1); } *got_frame = 1; - *(AVFrame*)data = s->frame; return pkt->size; } -static av_cold int aura_decode_end(AVCodecContext *avctx) -{ - AuraDecodeContext *s = avctx->priv_data; - - if (s->frame.data[0]) - avctx->release_buffer(avctx, &s->frame); - - return 0; -} - AVCodec ff_aura2_decoder = { .name = "aura2", .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_AURA2, - .priv_data_size = sizeof(AuraDecodeContext), .init = aura_decode_init, - .close = aura_decode_end, .decode = aura_decode_frame, .capabilities = CODEC_CAP_DR1, .long_name = NULL_IF_CONFIG_SMALL("Auravision Aura 2"), diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index 33f37e5e2f..b3bdb61bbd 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -823,6 +823,7 @@ typedef struct AVPanScan{ #define FF_QSCALE_TYPE_H264 2 #define FF_QSCALE_TYPE_VP56 3 +#if FF_API_GET_BUFFER #define FF_BUFFER_TYPE_INTERNAL 1 #define FF_BUFFER_TYPE_USER 2 ///< direct rendering buffers (image is (de)allocated by user) #define FF_BUFFER_TYPE_SHARED 4 ///< Buffer from somewhere else; don't deallocate image (data/base), all other tables are not shared. @@ -832,6 +833,12 @@ typedef struct AVPanScan{ #define FF_BUFFER_HINTS_READABLE 0x02 // Codec will read from buffer. #define FF_BUFFER_HINTS_PRESERVE 0x04 // User must not alter buffer content. #define FF_BUFFER_HINTS_REUSABLE 0x08 // Codec will reuse the buffer (update). +#endif + +/** + * The decoder will keep a reference to the frame and may reuse it later. + */ +#define AV_GET_BUFFER_FLAG_REF (1 << 0) /** * @defgroup lavc_packet AVPacket @@ -1859,6 +1866,7 @@ typedef struct AVCodecContext { */ enum AVSampleFormat request_sample_fmt; +#if FF_API_GET_BUFFER /** * Called at the beginning of each frame to get a buffer for it. * @@ -1918,7 +1926,10 @@ typedef struct AVCodecContext { * * - encoding: unused * - decoding: Set by libavcodec, user can override. + * + * @deprecated use get_buffer2() */ + attribute_deprecated int (*get_buffer)(struct AVCodecContext *c, AVFrame *pic); /** @@ -1929,7 +1940,10 @@ typedef struct AVCodecContext { * but not by more than one thread at once, so does not need to be reentrant. * - encoding: unused * - decoding: Set by libavcodec, user can override. + * + * @deprecated custom freeing callbacks should be set from get_buffer2() */ + attribute_deprecated void (*release_buffer)(struct AVCodecContext *c, AVFrame *pic); /** @@ -1944,8 +1958,100 @@ typedef struct AVCodecContext { * - encoding: unused * - decoding: Set by libavcodec, user can override. */ + attribute_deprecated int (*reget_buffer)(struct AVCodecContext *c, AVFrame *pic); +#endif + /** + * This callback is called at the beginning of each frame to get data + * buffer(s) for it. There may be one contiguous buffer for all the data or + * there may be a buffer per each data plane or anything in between. Each + * buffer must be reference-counted using the AVBuffer API. + * + * The following fields will be set in the frame before this callback is + * called: + * - format + * - width, height (video only) + * - sample_rate, channel_layout, nb_samples (audio only) + * Their values may differ from the corresponding values in + * AVCodecContext. This callback must use the frame values, not the codec + * context values, to calculate the required buffer size. + * + * This callback must fill the following fields in the frame: + * - data[] + * - linesize[] + * - extended_data: + * * if the data is planar audio with more than 8 channels, then this + * callback must allocate and fill extended_data to contain all pointers + * to all data planes. data[] must hold as many pointers as it can. + * extended_data must be allocated with av_malloc() and will be freed in + * av_frame_unref(). + * * otherwise exended_data must point to data + * - buf[] must contain references to the buffers that contain the frame + * data. + * - extended_buf and nb_extended_buf must be allocated with av_malloc() by + * this callback and filled with the extra buffers if there are more + * buffers than buf[] can hold. extended_buf will be freed in + * av_frame_unref(). + * + * If CODEC_CAP_DR1 is not set then get_buffer2() must call + * avcodec_default_get_buffer2() instead of providing buffers allocated by + * some other means. + * + * Each data plane must be aligned to the maximum required by the target + * CPU. + * + * @see avcodec_default_get_buffer2() + * + * Video: + * + * If AV_GET_BUFFER_FLAG_REF is set in flags then the frame may be reused + * (read and/or written to if it is writable) later by libavcodec. + * + * If CODEC_FLAG_EMU_EDGE is not set in s->flags, the buffer must contain an + * edge of the size returned by avcodec_get_edge_width() on all sides. + * + * avcodec_align_dimensions2() should be used to find the required width and + * height, as they normally need to be rounded up to the next multiple of 16. + * + * If frame multithreading is used and thread_safe_callbacks is set, + * this callback may be called from a different thread, but not from more + * than one at once. Does not need to be reentrant. + * + * @see avcodec_align_dimensions2() + * + * Audio: + * + * Decoders request a buffer of a particular size by setting + * AVFrame.nb_samples prior to calling get_buffer2(). The decoder may, + * however, utilize only part of the buffer by setting AVFrame.nb_samples + * to a smaller value in the output frame. + * + * As a convenience, av_samples_get_buffer_size() and + * av_samples_fill_arrays() in libavutil may be used by custom get_buffer2() + * functions to find the required data size and to fill data pointers and + * linesize. In AVFrame.linesize, only linesize[0] may be set for audio + * since all planes must be the same size. + * + * @see av_samples_get_buffer_size(), av_samples_fill_arrays() + * + * - encoding: unused + * - decoding: Set by libavcodec, user can override. + */ + int (*get_buffer2)(struct AVCodecContext *s, AVFrame *frame, int flags); + + /** + * If non-zero, the decoded audio and video frames returned from + * avcodec_decode_video2() and avcodec_decode_audio4() are reference-counted + * and are valid indefinitely. The caller must free them with + * av_frame_unref() when they are not needed anymore. + * Otherwise, the decoded frames must not be freed by the caller and are + * only valid until the next decode call. + * + * - encoding: unused + * - decoding: set by the caller before avcodec_open2(). + */ + int refcounted_frames; /* - encoding parameters */ float qcompress; ///< amount of qscale change between easy & hard scenes (0.0-1.0) @@ -3209,9 +3315,18 @@ AVCodec *avcodec_find_decoder(enum AVCodecID id); */ AVCodec *avcodec_find_decoder_by_name(const char *name); -int avcodec_default_get_buffer(AVCodecContext *s, AVFrame *pic); -void avcodec_default_release_buffer(AVCodecContext *s, AVFrame *pic); -int avcodec_default_reget_buffer(AVCodecContext *s, AVFrame *pic); +#if FF_API_GET_BUFFER +attribute_deprecated int avcodec_default_get_buffer(AVCodecContext *s, AVFrame *pic); +attribute_deprecated void avcodec_default_release_buffer(AVCodecContext *s, AVFrame *pic); +attribute_deprecated int avcodec_default_reget_buffer(AVCodecContext *s, AVFrame *pic); +#endif + +/** + * The default callback for AVCodecContext.get_buffer2(). It is made public so + * it can be called by custom get_buffer2() implementations for decoders without + * CODEC_CAP_DR1 set. + */ +int avcodec_default_get_buffer2(AVCodecContext *s, AVFrame *frame, int flags); /** * Return the amount of padding in pixels which the get_buffer callback must @@ -4147,8 +4262,6 @@ int avcodec_fill_audio_frame(AVFrame *frame, int nb_channels, */ void avcodec_flush_buffers(AVCodecContext *avctx); -void avcodec_default_free_buffers(AVCodecContext *s); - /** * Return codec bits per sample. * diff --git a/libavcodec/avs.c b/libavcodec/avs.c index 71b8b0c283..45cb4484d6 100644 --- a/libavcodec/avs.c +++ b/libavcodec/avs.c @@ -21,6 +21,7 @@ #include "avcodec.h" #include "get_bits.h" +#include "internal.h" typedef struct { @@ -59,11 +60,10 @@ avs_decode_frame(AVCodecContext * avctx, AvsBlockType type; GetBitContext change_map; - if ((ret = avctx->reget_buffer(avctx, p)) < 0) { + if ((ret = ff_reget_buffer(avctx, p)) < 0) { av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); return ret; } - p->reference = 1; p->pict_type = AV_PICTURE_TYPE_P; p->key_frame = 0; @@ -149,7 +149,8 @@ avs_decode_frame(AVCodecContext * avctx, align_get_bits(&change_map); } - *picture = avs->picture; + if ((ret = av_frame_ref(picture, &avs->picture)) < 0) + return ret; *got_frame = 1; return buf_size; @@ -165,8 +166,7 @@ static av_cold int avs_decode_init(AVCodecContext * avctx) static av_cold int avs_decode_end(AVCodecContext *avctx) { AvsContext *s = avctx->priv_data; - if (s->picture.data[0]) - avctx->release_buffer(avctx, &s->picture); + av_frame_unref(&s->picture); return 0; } diff --git a/libavcodec/bethsoftvideo.c b/libavcodec/bethsoftvideo.c index d0b34fdbe4..73145701ff 100644 --- a/libavcodec/bethsoftvideo.c +++ b/libavcodec/bethsoftvideo.c @@ -31,6 +31,7 @@ #include "avcodec.h" #include "bethsoftvideo.h" #include "bytestream.h" +#include "internal.h" typedef struct BethsoftvidContext { AVFrame frame; @@ -40,9 +41,6 @@ typedef struct BethsoftvidContext { static av_cold int bethsoftvid_decode_init(AVCodecContext *avctx) { BethsoftvidContext *vid = avctx->priv_data; - vid->frame.reference = 1; - vid->frame.buffer_hints = FF_BUFFER_HINTS_VALID | - FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE; avctx->pix_fmt = AV_PIX_FMT_PAL8; return 0; } @@ -75,7 +73,7 @@ static int bethsoftvid_decode_frame(AVCodecContext *avctx, int code, ret; int yoffset; - if ((ret = avctx->reget_buffer(avctx, &vid->frame)) < 0) { + if ((ret = ff_reget_buffer(avctx, &vid->frame)) < 0) { av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); return ret; } @@ -136,8 +134,10 @@ static int bethsoftvid_decode_frame(AVCodecContext *avctx, } end: + if ((ret = av_frame_ref(data, &vid->frame)) < 0) + return ret; + *got_frame = 1; - *(AVFrame*)data = vid->frame; return avpkt->size; } @@ -145,8 +145,7 @@ static int bethsoftvid_decode_frame(AVCodecContext *avctx, static av_cold int bethsoftvid_decode_end(AVCodecContext *avctx) { BethsoftvidContext * vid = avctx->priv_data; - if(vid->frame.data[0]) - avctx->release_buffer(avctx, &vid->frame); + av_frame_unref(&vid->frame); return 0; } diff --git a/libavcodec/bfi.c b/libavcodec/bfi.c index 1971c0c855..10544c5569 100644 --- a/libavcodec/bfi.c +++ b/libavcodec/bfi.c @@ -33,7 +33,6 @@ typedef struct BFIContext { AVCodecContext *avctx; - AVFrame frame; uint8_t *dst; } BFIContext; @@ -48,6 +47,7 @@ static av_cold int bfi_decode_init(AVCodecContext *avctx) static int bfi_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { + AVFrame *frame = data; GetByteContext g; int buf_size = avpkt->size; BFIContext *bfi = avctx->priv_data; @@ -57,12 +57,7 @@ static int bfi_decode_frame(AVCodecContext *avctx, void *data, uint32_t *pal; int i, j, ret, height = avctx->height; - if (bfi->frame.data[0]) - avctx->release_buffer(avctx, &bfi->frame); - - bfi->frame.reference = 1; - - if ((ret = ff_get_buffer(avctx, &bfi->frame)) < 0) { + if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } @@ -71,14 +66,14 @@ static int bfi_decode_frame(AVCodecContext *avctx, void *data, /* Set frame parameters and palette, if necessary */ if (!avctx->frame_number) { - bfi->frame.pict_type = AV_PICTURE_TYPE_I; - bfi->frame.key_frame = 1; + frame->pict_type = AV_PICTURE_TYPE_I; + frame->key_frame = 1; /* Setting the palette */ if (avctx->extradata_size > 768) { av_log(NULL, AV_LOG_ERROR, "Palette is too large.\n"); return AVERROR_INVALIDDATA; } - pal = (uint32_t *)bfi->frame.data[1]; + pal = (uint32_t *)frame->data[1]; for (i = 0; i < avctx->extradata_size / 3; i++) { int shift = 16; *pal = 0; @@ -87,10 +82,10 @@ static int bfi_decode_frame(AVCodecContext *avctx, void *data, (avctx->extradata[i * 3 + j] >> 4)) << shift; pal++; } - bfi->frame.palette_has_changed = 1; + frame->palette_has_changed = 1; } else { - bfi->frame.pict_type = AV_PICTURE_TYPE_P; - bfi->frame.key_frame = 0; + frame->pict_type = AV_PICTURE_TYPE_P; + frame->key_frame = 0; } bytestream2_skip(&g, 4); // Unpacked size, not required. @@ -158,22 +153,20 @@ static int bfi_decode_frame(AVCodecContext *avctx, void *data, } src = bfi->dst; - dst = bfi->frame.data[0]; + dst = frame->data[0]; while (height--) { memcpy(dst, src, avctx->width); src += avctx->width; - dst += bfi->frame.linesize[0]; + dst += frame->linesize[0]; } *got_frame = 1; - *(AVFrame *)data = bfi->frame; + return buf_size; } static av_cold int bfi_decode_close(AVCodecContext *avctx) { BFIContext *bfi = avctx->priv_data; - if (bfi->frame.data[0]) - avctx->release_buffer(avctx, &bfi->frame); av_free(bfi->dst); return 0; } diff --git a/libavcodec/bink.c b/libavcodec/bink.c index 033e9bf0a1..22e13c33dd 100644 --- a/libavcodec/bink.c +++ b/libavcodec/bink.c @@ -113,7 +113,7 @@ typedef struct BinkContext { AVCodecContext *avctx; DSPContext dsp; BinkDSPContext bdsp; - AVFrame *pic, *last; + AVFrame *last; int version; ///< internal Bink file version int has_alpha; int swap_planes; @@ -792,8 +792,8 @@ static inline void put_pixels8x8_overlapped(uint8_t *dst, uint8_t *src, int stri memcpy(dst + i*stride, tmp + i*8, 8); } -static int binkb_decode_plane(BinkContext *c, GetBitContext *gb, int plane_idx, - int is_key, int is_chroma) +static int binkb_decode_plane(BinkContext *c, AVFrame *frame, GetBitContext *gb, + int plane_idx, int is_key, int is_chroma) { int blk, ret; int i, j, bx, by; @@ -807,13 +807,13 @@ static int binkb_decode_plane(BinkContext *c, GetBitContext *gb, int plane_idx, int ybias = is_key ? -15 : 0; int qp; - const int stride = c->pic->linesize[plane_idx]; + const int stride = frame->linesize[plane_idx]; int bw = is_chroma ? (c->avctx->width + 15) >> 4 : (c->avctx->width + 7) >> 3; int bh = is_chroma ? (c->avctx->height + 15) >> 4 : (c->avctx->height + 7) >> 3; binkb_init_bundles(c); - ref_start = c->pic->data[plane_idx]; - ref_end = c->pic->data[plane_idx] + (bh * c->pic->linesize[plane_idx] + bw) * 8; + ref_start = frame->data[plane_idx]; + ref_end = frame->data[plane_idx] + (bh * frame->linesize[plane_idx] + bw) * 8; for (i = 0; i < 64; i++) coordmap[i] = (i & 7) + (i >> 3) * stride; @@ -824,7 +824,7 @@ static int binkb_decode_plane(BinkContext *c, GetBitContext *gb, int plane_idx, return ret; } - dst = c->pic->data[plane_idx] + 8*by*stride; + dst = frame->data[plane_idx] + 8*by*stride; for (bx = 0; bx < bw; bx++, dst += 8) { blk = binkb_get_value(c, BINKB_SRC_BLOCK_TYPES); switch (blk) { @@ -938,8 +938,8 @@ static int binkb_decode_plane(BinkContext *c, GetBitContext *gb, int plane_idx, return 0; } -static int bink_decode_plane(BinkContext *c, GetBitContext *gb, int plane_idx, - int is_chroma) +static int bink_decode_plane(BinkContext *c, AVFrame *frame, GetBitContext *gb, + int plane_idx, int is_chroma) { int blk, ret; int i, j, bx, by; @@ -952,7 +952,7 @@ static int bink_decode_plane(BinkContext *c, GetBitContext *gb, int plane_idx, LOCAL_ALIGNED_16(int32_t, dctblock, [64]); int coordmap[64]; - const int stride = c->pic->linesize[plane_idx]; + const int stride = frame->linesize[plane_idx]; int bw = is_chroma ? (c->avctx->width + 15) >> 4 : (c->avctx->width + 7) >> 3; int bh = is_chroma ? (c->avctx->height + 15) >> 4 : (c->avctx->height + 7) >> 3; int width = c->avctx->width >> is_chroma; @@ -962,7 +962,7 @@ static int bink_decode_plane(BinkContext *c, GetBitContext *gb, int plane_idx, read_bundle(gb, c, i); ref_start = c->last->data[plane_idx] ? c->last->data[plane_idx] - : c->pic->data[plane_idx]; + : frame->data[plane_idx]; ref_end = ref_start + (bw - 1 + c->last->linesize[plane_idx] * (bh - 1)) * 8; @@ -991,9 +991,9 @@ static int bink_decode_plane(BinkContext *c, GetBitContext *gb, int plane_idx, if (by == bh) break; - dst = c->pic->data[plane_idx] + 8*by*stride; + dst = frame->data[plane_idx] + 8*by*stride; prev = (c->last->data[plane_idx] ? c->last->data[plane_idx] - : c->pic->data[plane_idx]) + 8*by*stride; + : frame->data[plane_idx]) + 8*by*stride; for (bx = 0; bx < bw; bx++, dst += 8, prev += 8) { blk = get_value(c, BINK_SRC_BLOCK_TYPES); // 16x16 block type on odd line means part of the already decoded block, so skip it @@ -1165,30 +1165,30 @@ static int bink_decode_plane(BinkContext *c, GetBitContext *gb, int plane_idx, static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *pkt) { BinkContext * const c = avctx->priv_data; + AVFrame *frame = data; GetBitContext gb; int plane, plane_idx, ret; int bits_count = pkt->size << 3; if (c->version > 'b') { - if(c->pic->data[0]) - avctx->release_buffer(avctx, c->pic); - - if ((ret = ff_get_buffer(avctx, c->pic)) < 0) { + if ((ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } } else { - if ((ret = avctx->reget_buffer(avctx, c->pic)) < 0) { + if ((ret = ff_reget_buffer(avctx, c->last)) < 0) { av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); return ret; } + if ((ret = av_frame_ref(frame, c->last)) < 0) + return ret; } init_get_bits(&gb, pkt->data, bits_count); if (c->has_alpha) { if (c->version >= 'i') skip_bits_long(&gb, 32); - if ((ret = bink_decode_plane(c, &gb, 3, 0)) < 0) + if ((ret = bink_decode_plane(c, frame, &gb, 3, 0)) < 0) return ret; } if (c->version >= 'i') @@ -1198,10 +1198,10 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac plane_idx = (!plane || !c->swap_planes) ? plane : (plane ^ 3); if (c->version > 'b') { - if ((ret = bink_decode_plane(c, &gb, plane_idx, !!plane)) < 0) + if ((ret = bink_decode_plane(c, frame, &gb, plane_idx, !!plane)) < 0) return ret; } else { - if ((ret = binkb_decode_plane(c, &gb, plane_idx, + if ((ret = binkb_decode_plane(c, frame, &gb, plane_idx, !avctx->frame_number, !!plane)) < 0) return ret; } @@ -1210,11 +1210,13 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac } emms_c(); - *got_frame = 1; - *(AVFrame*)data = *c->pic; + if (c->version > 'b') { + av_frame_unref(c->last); + if ((ret = av_frame_ref(c->last, frame)) < 0) + return ret; + } - if (c->version > 'b') - FFSWAP(AVFrame*, c->pic, c->last); + *got_frame = 1; /* always report that the buffer was completely consumed */ return pkt->size; @@ -1293,13 +1295,9 @@ static av_cold int decode_init(AVCodecContext *avctx) } c->avctx = avctx; - c->pic = avcodec_alloc_frame(); - c->last = avcodec_alloc_frame(); - if (!c->pic || !c->last) { - avcodec_free_frame(&c->pic); - avcodec_free_frame(&c->last); + c->last = av_frame_alloc(); + if (!c->last) return AVERROR(ENOMEM); - } if ((ret = av_image_check_size(avctx->width, avctx->height, 0, avctx)) < 0) return ret; @@ -1325,12 +1323,7 @@ static av_cold int decode_end(AVCodecContext *avctx) { BinkContext * const c = avctx->priv_data; - if (c->pic->data[0]) - avctx->release_buffer(avctx, c->pic); - if (c->last->data[0]) - avctx->release_buffer(avctx, c->last); - avcodec_free_frame(&c->pic); - avcodec_free_frame(&c->last); + av_frame_free(&c->last); free_bundles(c); return 0; diff --git a/libavcodec/binkaudio.c b/libavcodec/binkaudio.c index dea1ffae50..1e34ab95fd 100644 --- a/libavcodec/binkaudio.c +++ b/libavcodec/binkaudio.c @@ -318,7 +318,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, /* get output buffer */ frame->nb_samples = s->frame_len; - if ((ret = ff_get_buffer(avctx, frame)) < 0) { + if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } diff --git a/libavcodec/bmp.c b/libavcodec/bmp.c index 5ca73baa4f..899fc8a1dc 100644 --- a/libavcodec/bmp.c +++ b/libavcodec/bmp.c @@ -25,25 +25,13 @@ #include "internal.h" #include "msrledec.h" -static av_cold int bmp_decode_init(AVCodecContext *avctx) -{ - BMPContext *s = avctx->priv_data; - - avcodec_get_frame_defaults(&s->picture); - avctx->coded_frame = &s->picture; - - return 0; -} - static int bmp_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; - BMPContext *s = avctx->priv_data; - AVFrame *picture = data; - AVFrame *p = &s->picture; + AVFrame *p = data; unsigned int fsize, hsize; int width, height; unsigned int depth; @@ -205,11 +193,7 @@ static int bmp_decode_frame(AVCodecContext *avctx, return AVERROR_INVALIDDATA; } - if (p->data[0]) - avctx->release_buffer(avctx, p); - - p->reference = 0; - if ((ret = ff_get_buffer(avctx, p)) < 0) { + if ((ret = ff_get_buffer(avctx, p, 0)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } @@ -350,29 +334,15 @@ static int bmp_decode_frame(AVCodecContext *avctx, } } - *picture = s->picture; *got_frame = 1; return buf_size; } -static av_cold int bmp_decode_end(AVCodecContext *avctx) -{ - BMPContext* c = avctx->priv_data; - - if (c->picture.data[0]) - avctx->release_buffer(avctx, &c->picture); - - return 0; -} - AVCodec ff_bmp_decoder = { .name = "bmp", .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_BMP, - .priv_data_size = sizeof(BMPContext), - .init = bmp_decode_init, - .close = bmp_decode_end, .decode = bmp_decode_frame, .capabilities = CODEC_CAP_DR1, .long_name = NULL_IF_CONFIG_SMALL("BMP (Windows and OS/2 bitmap)"), diff --git a/libavcodec/bmv.c b/libavcodec/bmv.c index 75c550f3f5..b6b685b556 100644 --- a/libavcodec/bmv.c +++ b/libavcodec/bmv.c @@ -43,7 +43,6 @@ enum BMVFlags{ typedef struct BMVDecContext { AVCodecContext *avctx; - AVFrame pic; uint8_t *frame, frame_base[SCREEN_WIDE * (SCREEN_HIGH + 1)]; uint32_t pal[256]; @@ -198,6 +197,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *pkt) { BMVDecContext * const c = avctx->priv_data; + AVFrame *frame = data; int type, scr_off; int i, ret; uint8_t *srcptr, *outptr; @@ -240,11 +240,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, scr_off = 0; } - if (c->pic.data[0]) - avctx->release_buffer(avctx, &c->pic); - - c->pic.reference = 3; - if ((ret = ff_get_buffer(avctx, &c->pic)) < 0) { + if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } @@ -254,20 +250,19 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, return AVERROR_INVALIDDATA; } - memcpy(c->pic.data[1], c->pal, AVPALETTE_SIZE); - c->pic.palette_has_changed = type & BMV_PALETTE; + memcpy(frame->data[1], c->pal, AVPALETTE_SIZE); + frame->palette_has_changed = type & BMV_PALETTE; - outptr = c->pic.data[0]; + outptr = frame->data[0]; srcptr = c->frame; for (i = 0; i < avctx->height; i++) { memcpy(outptr, srcptr, avctx->width); srcptr += avctx->width; - outptr += c->pic.linesize[0]; + outptr += frame->linesize[0]; } *got_frame = 1; - *(AVFrame*)data = c->pic; /* always report that the buffer was completely consumed */ return pkt->size; @@ -285,16 +280,6 @@ static av_cold int decode_init(AVCodecContext *avctx) return 0; } -static av_cold int decode_end(AVCodecContext *avctx) -{ - BMVDecContext *c = avctx->priv_data; - - if (c->pic.data[0]) - avctx->release_buffer(avctx, &c->pic); - - return 0; -} - static const int bmv_aud_mults[16] = { 16512, 8256, 4128, 2064, 1032, 516, 258, 192, 129, 88, 64, 56, 48, 40, 36, 32 }; @@ -328,7 +313,7 @@ static int bmv_aud_decode_frame(AVCodecContext *avctx, void *data, /* get output buffer */ frame->nb_samples = total_blocks * 32; - if ((ret = ff_get_buffer(avctx, frame)) < 0) { + if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } @@ -356,7 +341,6 @@ AVCodec ff_bmv_video_decoder = { .id = AV_CODEC_ID_BMV_VIDEO, .priv_data_size = sizeof(BMVDecContext), .init = decode_init, - .close = decode_end, .decode = decode_frame, .capabilities = CODEC_CAP_DR1, .long_name = NULL_IF_CONFIG_SMALL("Discworld II BMV video"), diff --git a/libavcodec/c93.c b/libavcodec/c93.c index b7205855bb..750941e021 100644 --- a/libavcodec/c93.c +++ b/libavcodec/c93.c @@ -21,6 +21,7 @@ #include "avcodec.h" #include "bytestream.h" +#include "internal.h" typedef struct { AVFrame pictures[2]; @@ -55,10 +56,9 @@ static av_cold int decode_end(AVCodecContext *avctx) { C93DecoderContext * const c93 = avctx->priv_data; - if (c93->pictures[0].data[0]) - avctx->release_buffer(avctx, &c93->pictures[0]); - if (c93->pictures[1].data[0]) - avctx->release_buffer(avctx, &c93->pictures[1]); + av_frame_unref(&c93->pictures[0]); + av_frame_unref(&c93->pictures[1]); + return 0; } @@ -120,17 +120,13 @@ static int decode_frame(AVCodecContext *avctx, void *data, C93DecoderContext * const c93 = avctx->priv_data; AVFrame * const newpic = &c93->pictures[c93->currentpic]; AVFrame * const oldpic = &c93->pictures[c93->currentpic^1]; - AVFrame *picture = data; GetByteContext gb; uint8_t *out; int stride, ret, i, x, y, b, bt = 0; c93->currentpic ^= 1; - newpic->reference = 1; - newpic->buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | - FF_BUFFER_HINTS_REUSABLE | FF_BUFFER_HINTS_READABLE; - if ((ret = avctx->reget_buffer(avctx, newpic)) < 0) { + if ((ret = ff_reget_buffer(avctx, newpic)) < 0) { av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); return ret; } @@ -239,7 +235,8 @@ static int decode_frame(AVCodecContext *avctx, void *data, memcpy(newpic->data[1], oldpic->data[1], 256 * 4); } - *picture = *newpic; + if ((ret = av_frame_ref(data, newpic)) < 0) + return ret; *got_frame = 1; return buf_size; diff --git a/libavcodec/cavs.c b/libavcodec/cavs.c index e6315bc291..abd4bacdda 100644 --- a/libavcodec/cavs.c +++ b/libavcodec/cavs.c @@ -736,9 +736,9 @@ av_cold int ff_cavs_init(AVCodecContext *avctx) { h->avctx = avctx; avctx->pix_fmt= AV_PIX_FMT_YUV420P; - h->cur.f = avcodec_alloc_frame(); - h->DPB[0].f = avcodec_alloc_frame(); - h->DPB[1].f = avcodec_alloc_frame(); + h->cur.f = av_frame_alloc(); + h->DPB[0].f = av_frame_alloc(); + h->DPB[1].f = av_frame_alloc(); if (!h->cur.f || !h->DPB[0].f || !h->DPB[1].f) { ff_cavs_end(avctx); return AVERROR(ENOMEM); @@ -769,15 +769,9 @@ av_cold int ff_cavs_init(AVCodecContext *avctx) { av_cold int ff_cavs_end(AVCodecContext *avctx) { AVSContext *h = avctx->priv_data; - if (h->cur.f->data[0]) - avctx->release_buffer(avctx, h->cur.f); - if (h->DPB[0].f->data[0]) - avctx->release_buffer(avctx, h->DPB[0].f); - if (h->DPB[1].f->data[0]) - avctx->release_buffer(avctx, h->DPB[1].f); - avcodec_free_frame(&h->cur.f); - avcodec_free_frame(&h->DPB[0].f); - avcodec_free_frame(&h->DPB[1].f); + av_frame_free(&h->cur.f); + av_frame_free(&h->DPB[0].f); + av_frame_free(&h->DPB[1].f); av_free(h->top_qp); av_free(h->top_mv[0]); diff --git a/libavcodec/cavsdec.c b/libavcodec/cavsdec.c index b841f48d13..fbc21c4d81 100644 --- a/libavcodec/cavsdec.c +++ b/libavcodec/cavsdec.c @@ -931,6 +931,8 @@ static int decode_pic(AVSContext *h) int skip_count = -1; enum cavs_mb mb_type; + av_frame_unref(h->cur.f); + skip_bits(&h->gb, 16);//bbv_dwlay if (h->stc == PIC_PB_START_CODE) { h->cur.f->pict_type = get_bits(&h->gb, 2) + AV_PICTURE_TYPE_I; @@ -956,11 +958,9 @@ static int decode_pic(AVSContext *h) if (h->stream_revision > 0) skip_bits(&h->gb, 1); //marker_bit } - /* release last B frame */ - if (h->cur.f->data[0]) - h->avctx->release_buffer(h->avctx, h->cur.f); - ff_get_buffer(h->avctx, h->cur.f); + ff_get_buffer(h->avctx, h->cur.f, h->cur.f->pict_type == AV_PICTURE_TYPE_B ? + 0 : AV_GET_BUFFER_FLAG_REF); if (!h->edge_emu_buffer) { int alloc_size = FFALIGN(FFABS(h->cur.f->linesize[0]) + 32, 32); @@ -1056,8 +1056,7 @@ static int decode_pic(AVSContext *h) } while (ff_cavs_next_mb(h)); } if (h->cur.f->pict_type != AV_PICTURE_TYPE_B) { - if (h->DPB[1].f->data[0]) - h->avctx->release_buffer(h->avctx, h->DPB[1].f); + av_frame_unref(h->DPB[1].f); FFSWAP(AVSFrame, h->cur, h->DPB[1]); FFSWAP(AVSFrame, h->DPB[0], h->DPB[1]); } @@ -1119,19 +1118,15 @@ static int cavs_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVSContext *h = avctx->priv_data; const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; - AVFrame *picture = data; uint32_t stc = -1; - int input_size; + int input_size, ret; const uint8_t *buf_end; const uint8_t *buf_ptr; if (buf_size == 0) { if (!h->low_delay && h->DPB[0].f->data[0]) { *got_frame = 1; - *picture = *h->DPB[0].f; - if (h->cur.f->data[0]) - avctx->release_buffer(avctx, h->cur.f); - FFSWAP(AVSFrame, h->cur, h->DPB[0]); + av_frame_move_ref(data, h->DPB[0].f); } return 0; } @@ -1150,10 +1145,8 @@ static int cavs_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, break; case PIC_I_START_CODE: if (!h->got_keyframe) { - if(h->DPB[0].f->data[0]) - avctx->release_buffer(avctx, h->DPB[0].f); - if(h->DPB[1].f->data[0]) - avctx->release_buffer(avctx, h->DPB[1].f); + av_frame_unref(h->DPB[0].f); + av_frame_unref(h->DPB[1].f); h->got_keyframe = 1; } case PIC_PB_START_CODE: @@ -1167,12 +1160,14 @@ static int cavs_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, *got_frame = 1; if (h->cur.f->pict_type != AV_PICTURE_TYPE_B) { if (h->DPB[1].f->data[0]) { - *picture = *h->DPB[1].f; + if ((ret = av_frame_ref(data, h->DPB[1].f)) < 0) + return ret; } else { *got_frame = 0; } - } else - *picture = *h->cur.f; + } else { + av_frame_move_ref(data, h->cur.f); + } break; case EXT_START_CODE: //mpeg_decode_extension(avctx, buf_ptr, input_size); diff --git a/libavcodec/cdgraphics.c b/libavcodec/cdgraphics.c index 9f402cae21..8be14602c3 100644 --- a/libavcodec/cdgraphics.c +++ b/libavcodec/cdgraphics.c @@ -64,26 +64,18 @@ #define CDG_PALETTE_SIZE 16 typedef struct CDGraphicsContext { - AVFrame frame; + AVFrame *frame; int hscroll; int vscroll; } CDGraphicsContext; -static void cdg_init_frame(AVFrame *frame) -{ - avcodec_get_frame_defaults(frame); - frame->reference = 3; - frame->buffer_hints = FF_BUFFER_HINTS_VALID | - FF_BUFFER_HINTS_READABLE | - FF_BUFFER_HINTS_PRESERVE | - FF_BUFFER_HINTS_REUSABLE; -} - static av_cold int cdg_decode_init(AVCodecContext *avctx) { CDGraphicsContext *cc = avctx->priv_data; - cdg_init_frame(&cc->frame); + cc->frame = av_frame_alloc(); + if (!cc->frame) + return AVERROR(ENOMEM); avctx->width = CDG_FULL_WIDTH; avctx->height = CDG_FULL_HEIGHT; @@ -95,8 +87,8 @@ static av_cold int cdg_decode_init(AVCodecContext *avctx) static void cdg_border_preset(CDGraphicsContext *cc, uint8_t *data) { int y; - int lsize = cc->frame.linesize[0]; - uint8_t *buf = cc->frame.data[0]; + int lsize = cc->frame->linesize[0]; + uint8_t *buf = cc->frame->data[0]; int color = data[0] & 0x0F; if (!(data[1] & 0x0F)) { @@ -120,7 +112,7 @@ static void cdg_load_palette(CDGraphicsContext *cc, uint8_t *data, int low) uint16_t color; int i; int array_offset = low ? 0 : 8; - uint32_t *palette = (uint32_t *) cc->frame.data[1]; + uint32_t *palette = (uint32_t *) cc->frame->data[1]; for (i = 0; i < 8; i++) { color = (data[2 * i] << 6) + (data[2 * i + 1] & 0x3F); @@ -129,7 +121,7 @@ static void cdg_load_palette(CDGraphicsContext *cc, uint8_t *data, int low) b = ((color ) & 0x000F) * 17; palette[i + array_offset] = r << 16 | g << 8 | b; } - cc->frame.palette_has_changed = 1; + cc->frame->palette_has_changed = 1; } static int cdg_tile_block(CDGraphicsContext *cc, uint8_t *data, int b) @@ -138,8 +130,8 @@ static int cdg_tile_block(CDGraphicsContext *cc, uint8_t *data, int b) int color; int x, y; int ai; - int stride = cc->frame.linesize[0]; - uint8_t *buf = cc->frame.data[0]; + int stride = cc->frame->linesize[0]; + uint8_t *buf = cc->frame->data[0]; ri = (data[2] & 0x1F) * CDG_TILE_HEIGHT + cc->vscroll; ci = (data[3] & 0x3F) * CDG_TILE_WIDTH + cc->hscroll; @@ -210,8 +202,8 @@ static void cdg_scroll(CDGraphicsContext *cc, uint8_t *data, int color; int hscmd, h_off, hinc, vscmd, v_off, vinc; int y; - int stride = cc->frame.linesize[0]; - uint8_t *in = cc->frame.data[0]; + int stride = cc->frame->linesize[0]; + uint8_t *in = cc->frame->data[0]; uint8_t *out = new_frame->data[0]; color = data[0] & 0x0F; @@ -239,7 +231,7 @@ static void cdg_scroll(CDGraphicsContext *cc, uint8_t *data, if (!hinc && !vinc) return; - memcpy(new_frame->data[1], cc->frame.data[1], CDG_PALETTE_SIZE * 4); + memcpy(new_frame->data[1], cc->frame->data[1], CDG_PALETTE_SIZE * 4); for (y = FFMAX(0, vinc); y < FFMIN(CDG_FULL_HEIGHT + vinc, CDG_FULL_HEIGHT); y++) memcpy(out + FFMAX(0, hinc) + stride * y, @@ -274,7 +266,7 @@ static int cdg_decode_frame(AVCodecContext *avctx, int ret; uint8_t command, inst; uint8_t cdg_data[CDG_DATA_SIZE]; - AVFrame new_frame; + AVFrame *frame = data; CDGraphicsContext *cc = avctx->priv_data; if (buf_size < CDG_MINIMUM_PKT_SIZE) { @@ -282,13 +274,13 @@ static int cdg_decode_frame(AVCodecContext *avctx, return AVERROR(EINVAL); } - ret = avctx->reget_buffer(avctx, &cc->frame); + ret = ff_reget_buffer(avctx, cc->frame); if (ret) { av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); return ret; } if (!avctx->frame_number) - memset(cc->frame.data[0], 0, cc->frame.linesize[0] * avctx->height); + memset(cc->frame->data[0], 0, cc->frame->linesize[0] * avctx->height); command = bytestream_get_byte(&buf); inst = bytestream_get_byte(&buf); @@ -300,8 +292,8 @@ static int cdg_decode_frame(AVCodecContext *avctx, switch (inst) { case CDG_INST_MEMORY_PRESET: if (!(cdg_data[1] & 0x0F)) - memset(cc->frame.data[0], cdg_data[0] & 0x0F, - cc->frame.linesize[0] * CDG_FULL_HEIGHT); + memset(cc->frame->data[0], cdg_data[0] & 0x0F, + cc->frame->linesize[0] * CDG_FULL_HEIGHT); break; case CDG_INST_LOAD_PAL_LO: case CDG_INST_LOAD_PAL_HIGH: @@ -335,28 +327,33 @@ static int cdg_decode_frame(AVCodecContext *avctx, return AVERROR(EINVAL); } - cdg_init_frame(&new_frame); - ret = ff_get_buffer(avctx, &new_frame); + ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF); if (ret) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } - cdg_scroll(cc, cdg_data, &new_frame, inst == CDG_INST_SCROLL_COPY); - avctx->release_buffer(avctx, &cc->frame); - cc->frame = new_frame; + cdg_scroll(cc, cdg_data, frame, inst == CDG_INST_SCROLL_COPY); + av_frame_unref(cc->frame); + ret = av_frame_ref(cc->frame, frame); + if (ret < 0) + return ret; break; default: break; } + if (!frame->data[0]) { + ret = av_frame_ref(frame, cc->frame); + if (ret < 0) + return ret; + } *got_frame = 1; } else { *got_frame = 0; buf_size = 0; } - *(AVFrame *) data = cc->frame; return buf_size; } @@ -364,8 +361,7 @@ static av_cold int cdg_decode_end(AVCodecContext *avctx) { CDGraphicsContext *cc = avctx->priv_data; - if (cc->frame.data[0]) - avctx->release_buffer(avctx, &cc->frame); + av_frame_free(&cc->frame); return 0; } diff --git a/libavcodec/cdxl.c b/libavcodec/cdxl.c index 0b3d59cb80..465867c098 100644 --- a/libavcodec/cdxl.c +++ b/libavcodec/cdxl.c @@ -49,7 +49,6 @@ static av_cold int cdxl_decode_init(AVCodecContext *avctx) { CDXLVideoContext *c = avctx->priv_data; - avcodec_get_frame_defaults(&c->frame); c->new_video_size = 0; c->avctx = avctx; @@ -113,15 +112,15 @@ static void import_format(CDXLVideoContext *c, int linesize, uint8_t *out) } } -static void cdxl_decode_rgb(CDXLVideoContext *c) +static void cdxl_decode_rgb(CDXLVideoContext *c, AVFrame *frame) { - uint32_t *new_palette = (uint32_t *)c->frame.data[1]; + uint32_t *new_palette = (uint32_t *)frame->data[1]; import_palette(c, new_palette); - import_format(c, c->frame.linesize[0], c->frame.data[0]); + import_format(c, frame->linesize[0], frame->data[0]); } -static void cdxl_decode_ham6(CDXLVideoContext *c) +static void cdxl_decode_ham6(CDXLVideoContext *c, AVFrame *frame) { AVCodecContext *avctx = c->avctx; uint32_t new_palette[16], r, g, b; @@ -129,7 +128,7 @@ static void cdxl_decode_ham6(CDXLVideoContext *c) int x, y; ptr = c->new_video; - out = c->frame.data[0]; + out = frame->data[0]; import_palette(c, new_palette); import_format(c, avctx->width, c->new_video); @@ -160,11 +159,11 @@ static void cdxl_decode_ham6(CDXLVideoContext *c) } AV_WL24(out + x * 3, r | g | b); } - out += c->frame.linesize[0]; + out += frame->linesize[0]; } } -static void cdxl_decode_ham8(CDXLVideoContext *c) +static void cdxl_decode_ham8(CDXLVideoContext *c, AVFrame *frame) { AVCodecContext *avctx = c->avctx; uint32_t new_palette[64], r, g, b; @@ -172,7 +171,7 @@ static void cdxl_decode_ham8(CDXLVideoContext *c) int x, y; ptr = c->new_video; - out = c->frame.data[0]; + out = frame->data[0]; import_palette(c, new_palette); import_format(c, avctx->width, c->new_video); @@ -203,7 +202,7 @@ static void cdxl_decode_ham8(CDXLVideoContext *c) } AV_WL24(out + x * 3, r | g | b); } - out += c->frame.linesize[0]; + out += frame->linesize[0]; } } @@ -211,7 +210,7 @@ static int cdxl_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *pkt) { CDXLVideoContext *c = avctx->priv_data; - AVFrame * const p = &c->frame; + AVFrame * const p = data; int ret, w, h, encoding, aligned_width, buf_size = pkt->size; const uint8_t *buf = pkt->data; @@ -259,11 +258,7 @@ static int cdxl_decode_frame(AVCodecContext *avctx, void *data, return AVERROR_PATCHWELCOME; } - if (p->data[0]) - avctx->release_buffer(avctx, p); - - p->reference = 0; - if ((ret = ff_get_buffer(avctx, p)) < 0) { + if ((ret = ff_get_buffer(avctx, p, 0)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } @@ -275,14 +270,13 @@ static int cdxl_decode_frame(AVCodecContext *avctx, void *data, if (!c->new_video) return AVERROR(ENOMEM); if (c->bpp == 8) - cdxl_decode_ham8(c); + cdxl_decode_ham8(c, p); else - cdxl_decode_ham6(c); + cdxl_decode_ham6(c, p); } else { - cdxl_decode_rgb(c); + cdxl_decode_rgb(c, p); } *got_frame = 1; - *(AVFrame*)data = c->frame; return buf_size; } @@ -292,8 +286,6 @@ static av_cold int cdxl_decode_end(AVCodecContext *avctx) CDXLVideoContext *c = avctx->priv_data; av_free(c->new_video); - if (c->frame.data[0]) - avctx->release_buffer(avctx, &c->frame); return 0; } diff --git a/libavcodec/cinepak.c b/libavcodec/cinepak.c index 9bf68634a9..0c5d5b0f0d 100644 --- a/libavcodec/cinepak.c +++ b/libavcodec/cinepak.c @@ -37,6 +37,7 @@ #include "libavutil/common.h" #include "libavutil/intreadwrite.h" #include "avcodec.h" +#include "internal.h" typedef struct { @@ -429,10 +430,7 @@ static int cinepak_decode_frame(AVCodecContext *avctx, s->data = buf; s->size = buf_size; - s->frame.reference = 1; - s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | - FF_BUFFER_HINTS_REUSABLE; - if ((ret = avctx->reget_buffer(avctx, &s->frame))) { + if ((ret = ff_reget_buffer(avctx, &s->frame))) { av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); return ret; } @@ -450,8 +448,10 @@ static int cinepak_decode_frame(AVCodecContext *avctx, if (s->palette_video) memcpy (s->frame.data[1], s->pal, AVPALETTE_SIZE); + if ((ret = av_frame_ref(data, &s->frame)) < 0) + return ret; + *got_frame = 1; - *(AVFrame*)data = s->frame; /* report that the buffer was completely consumed */ return buf_size; @@ -461,8 +461,7 @@ static av_cold int cinepak_decode_end(AVCodecContext *avctx) { CinepakContext *s = avctx->priv_data; - if (s->frame.data[0]) - avctx->release_buffer(avctx, &s->frame); + av_frame_unref(&s->frame); return 0; } diff --git a/libavcodec/cljr.c b/libavcodec/cljr.c index 5168d34571..7e189cd12d 100644 --- a/libavcodec/cljr.c +++ b/libavcodec/cljr.c @@ -29,19 +29,6 @@ #include "internal.h" #include "put_bits.h" -typedef struct CLJRContext { - AVFrame picture; -} CLJRContext; - -static av_cold int common_init(AVCodecContext *avctx) -{ - CLJRContext * const a = avctx->priv_data; - - avctx->coded_frame = &a->picture; - - return 0; -} - #if CONFIG_CLJR_DECODER static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, @@ -49,15 +36,10 @@ static int decode_frame(AVCodecContext *avctx, { const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; - CLJRContext * const a = avctx->priv_data; GetBitContext gb; - AVFrame *picture = data; - AVFrame * const p = &a->picture; + AVFrame * const p = data; int x, y, ret; - if (p->data[0]) - avctx->release_buffer(avctx, p); - if (avctx->height <= 0 || avctx->width <= 0) { av_log(avctx, AV_LOG_ERROR, "Invalid width or height\n"); return AVERROR_INVALIDDATA; @@ -69,8 +51,7 @@ static int decode_frame(AVCodecContext *avctx, return AVERROR_INVALIDDATA; } - p->reference = 0; - if ((ret = ff_get_buffer(avctx, p)) < 0) { + if ((ret = ff_get_buffer(avctx, p, 0)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } @@ -80,9 +61,9 @@ static int decode_frame(AVCodecContext *avctx, init_get_bits(&gb, buf, buf_size * 8); for (y = 0; y < avctx->height; y++) { - uint8_t *luma = &a->picture.data[0][y * a->picture.linesize[0]]; - uint8_t *cb = &a->picture.data[1][y * a->picture.linesize[1]]; - uint8_t *cr = &a->picture.data[2][y * a->picture.linesize[2]]; + uint8_t *luma = &p->data[0][y * p->linesize[0]]; + uint8_t *cb = &p->data[1][y * p->linesize[1]]; + uint8_t *cr = &p->data[2][y * p->linesize[2]]; for (x = 0; x < avctx->width; x += 4) { luma[3] = get_bits(&gb, 5) << 3; luma[2] = get_bits(&gb, 5) << 3; @@ -94,7 +75,6 @@ static int decode_frame(AVCodecContext *avctx, } } - *picture = a->picture; *got_frame = 1; return buf_size; @@ -103,15 +83,6 @@ static int decode_frame(AVCodecContext *avctx, static av_cold int decode_init(AVCodecContext *avctx) { avctx->pix_fmt = AV_PIX_FMT_YUV411P; - return common_init(avctx); -} - -static av_cold int decode_end(AVCodecContext *avctx) -{ - CLJRContext *a = avctx->priv_data; - - if (a->picture.data[0]) - avctx->release_buffer(avctx, &a->picture); return 0; } @@ -119,9 +90,7 @@ AVCodec ff_cljr_decoder = { .name = "cljr", .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_CLJR, - .priv_data_size = sizeof(CLJRContext), .init = decode_init, - .close = decode_end, .decode = decode_frame, .capabilities = CODEC_CAP_DR1, .long_name = NULL_IF_CONFIG_SMALL("Cirrus Logic AccuPak"), @@ -129,6 +98,19 @@ AVCodec ff_cljr_decoder = { #endif #if CONFIG_CLJR_ENCODER +typedef struct CLJRContext { + AVFrame picture; +} CLJRContext; + +static av_cold int encode_init(AVCodecContext *avctx) +{ + CLJRContext * const a = avctx->priv_data; + + avctx->coded_frame = &a->picture; + + return 0; +} + static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *p, int *got_packet) { @@ -173,7 +155,7 @@ AVCodec ff_cljr_encoder = { .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_CLJR, .priv_data_size = sizeof(CLJRContext), - .init = common_init, + .init = encode_init, .encode2 = encode_frame, .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV411P, AV_PIX_FMT_NONE }, diff --git a/libavcodec/cllc.c b/libavcodec/cllc.c index 30dc53c6e1..a6b51b398e 100644 --- a/libavcodec/cllc.c +++ b/libavcodec/cllc.c @@ -271,18 +271,13 @@ static int cllc_decode_frame(AVCodecContext *avctx, void *data, int *got_picture_ptr, AVPacket *avpkt) { CLLCContext *ctx = avctx->priv_data; - AVFrame *pic = avctx->coded_frame; + AVFrame *pic = data; uint8_t *src = avpkt->data; uint32_t info_tag, info_offset; int data_size; GetBitContext gb; int coding_type, ret; - if (pic->data[0]) - avctx->release_buffer(avctx, pic); - - pic->reference = 0; - /* Skip the INFO header if present */ info_offset = 0; info_tag = AV_RL32(src); @@ -334,7 +329,7 @@ static int cllc_decode_frame(AVCodecContext *avctx, void *data, avctx->pix_fmt = AV_PIX_FMT_RGB24; avctx->bits_per_raw_sample = 8; - ret = ff_get_buffer(avctx, pic); + ret = ff_get_buffer(avctx, pic, 0); if (ret < 0) { av_log(avctx, AV_LOG_ERROR, "Could not allocate buffer.\n"); return ret; @@ -349,7 +344,7 @@ static int cllc_decode_frame(AVCodecContext *avctx, void *data, avctx->pix_fmt = AV_PIX_FMT_ARGB; avctx->bits_per_raw_sample = 8; - ret = ff_get_buffer(avctx, pic); + ret = ff_get_buffer(avctx, pic, 0); if (ret < 0) { av_log(avctx, AV_LOG_ERROR, "Could not allocate buffer.\n"); return ret; @@ -369,7 +364,6 @@ static int cllc_decode_frame(AVCodecContext *avctx, void *data, pic->pict_type = AV_PICTURE_TYPE_I; *got_picture_ptr = 1; - *(AVFrame *)data = *pic; return avpkt->size; } @@ -378,10 +372,6 @@ static av_cold int cllc_decode_close(AVCodecContext *avctx) { CLLCContext *ctx = avctx->priv_data; - if (avctx->coded_frame->data[0]) - avctx->release_buffer(avctx, avctx->coded_frame); - - av_freep(&avctx->coded_frame); av_freep(&ctx->swapped_buf); return 0; @@ -398,12 +388,6 @@ static av_cold int cllc_decode_init(AVCodecContext *avctx) ff_dsputil_init(&ctx->dsp, avctx); - avctx->coded_frame = avcodec_alloc_frame(); - if (!avctx->coded_frame) { - av_log(avctx, AV_LOG_ERROR, "Could not allocate frame.\n"); - return AVERROR(ENOMEM); - } - return 0; } diff --git a/libavcodec/cngdec.c b/libavcodec/cngdec.c index b47cda8974..a9b3ba0a75 100644 --- a/libavcodec/cngdec.c +++ b/libavcodec/cngdec.c @@ -142,7 +142,7 @@ static int cng_decode_frame(AVCodecContext *avctx, void *data, p->excitation, avctx->frame_size, p->order); frame->nb_samples = avctx->frame_size; - if ((ret = ff_get_buffer(avctx, frame)) < 0) { + if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } diff --git a/libavcodec/cook.c b/libavcodec/cook.c index ba542c2e1e..135359bcd4 100644 --- a/libavcodec/cook.c +++ b/libavcodec/cook.c @@ -958,7 +958,7 @@ static int cook_decode_frame(AVCodecContext *avctx, void *data, /* get output buffer */ if (q->discarded_packets >= 2) { frame->nb_samples = q->samples_per_channel; - if ((ret = ff_get_buffer(avctx, frame)) < 0) { + if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } diff --git a/libavcodec/cscd.c b/libavcodec/cscd.c index b982f5029c..6b8d144f76 100644 --- a/libavcodec/cscd.c +++ b/libavcodec/cscd.c @@ -31,7 +31,6 @@ #include "libavutil/lzo.h" typedef struct { - AVFrame pic; int linelen, height, bpp; unsigned int decomp_size; unsigned char* decomp_buf; @@ -150,12 +149,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, return AVERROR_INVALIDDATA; } - if (c->pic.data[0]) - avctx->release_buffer(avctx, &c->pic); - c->pic.reference = 1; - c->pic.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_READABLE | - FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE; - if ((ret = ff_get_buffer(avctx, &c->pic)) < 0) { + if ((ret = ff_get_buffer(avctx, picture, 0)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } @@ -186,36 +180,35 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, // flip upside down, add difference frame if (buf[0] & 1) { // keyframe - c->pic.pict_type = AV_PICTURE_TYPE_I; - c->pic.key_frame = 1; + picture->pict_type = AV_PICTURE_TYPE_I; + picture->key_frame = 1; switch (c->bpp) { case 16: - copy_frame_16(&c->pic, c->decomp_buf, c->linelen, c->height); + copy_frame_16(picture, c->decomp_buf, c->linelen, c->height); break; case 32: - copy_frame_32(&c->pic, c->decomp_buf, c->linelen, c->height); + copy_frame_32(picture, c->decomp_buf, c->linelen, c->height); break; default: - copy_frame_default(&c->pic, c->decomp_buf, FFALIGN(c->linelen, 4), + copy_frame_default(picture, c->decomp_buf, FFALIGN(c->linelen, 4), c->linelen, c->height); } } else { - c->pic.pict_type = AV_PICTURE_TYPE_P; - c->pic.key_frame = 0; + picture->pict_type = AV_PICTURE_TYPE_P; + picture->key_frame = 0; switch (c->bpp) { case 16: - add_frame_16(&c->pic, c->decomp_buf, c->linelen, c->height); + add_frame_16(picture, c->decomp_buf, c->linelen, c->height); break; case 32: - add_frame_32(&c->pic, c->decomp_buf, c->linelen, c->height); + add_frame_32(picture, c->decomp_buf, c->linelen, c->height); break; default: - add_frame_default(&c->pic, c->decomp_buf, FFALIGN(c->linelen, 4), + add_frame_default(picture, c->decomp_buf, FFALIGN(c->linelen, 4), c->linelen, c->height); } } - *picture = c->pic; *got_frame = 1; return buf_size; } @@ -234,7 +227,6 @@ static av_cold int decode_init(AVCodecContext *avctx) { return AVERROR_INVALIDDATA; } c->bpp = avctx->bits_per_coded_sample; - c->pic.data[0] = NULL; c->linelen = avctx->width * avctx->bits_per_coded_sample / 8; c->height = avctx->height; stride = c->linelen; @@ -252,8 +244,6 @@ static av_cold int decode_init(AVCodecContext *avctx) { static av_cold int decode_end(AVCodecContext *avctx) { CamStudioContext *c = avctx->priv_data; av_freep(&c->decomp_buf); - if (c->pic.data[0]) - avctx->release_buffer(avctx, &c->pic); return 0; } diff --git a/libavcodec/cyuv.c b/libavcodec/cyuv.c index 6b9d5b9307..9011bc2cfd 100644 --- a/libavcodec/cyuv.c +++ b/libavcodec/cyuv.c @@ -40,7 +40,6 @@ typedef struct CyuvDecodeContext { AVCodecContext *avctx; int width, height; - AVFrame frame; } CyuvDecodeContext; static av_cold int cyuv_decode_init(AVCodecContext *avctx) @@ -65,6 +64,7 @@ static int cyuv_decode_frame(AVCodecContext *avctx, const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; CyuvDecodeContext *s=avctx->priv_data; + AVFrame *frame = data; unsigned char *y_plane; unsigned char *u_plane; @@ -101,26 +101,21 @@ static int cyuv_decode_frame(AVCodecContext *avctx, /* pixel data starts 48 bytes in, after 3x16-byte tables */ stream_ptr = 48; - if (s->frame.data[0]) - avctx->release_buffer(avctx, &s->frame); - - s->frame.buffer_hints = FF_BUFFER_HINTS_VALID; - s->frame.reference = 0; - if ((ret = ff_get_buffer(avctx, &s->frame)) < 0) { + if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } - y_plane = s->frame.data[0]; - u_plane = s->frame.data[1]; - v_plane = s->frame.data[2]; + y_plane = frame->data[0]; + u_plane = frame->data[1]; + v_plane = frame->data[2]; /* iterate through each line in the height */ for (y_ptr = 0, u_ptr = 0, v_ptr = 0; - y_ptr < (s->height * s->frame.linesize[0]); - y_ptr += s->frame.linesize[0] - s->width, - u_ptr += s->frame.linesize[1] - s->width / 4, - v_ptr += s->frame.linesize[2] - s->width / 4) { + y_ptr < (s->height * frame->linesize[0]); + y_ptr += frame->linesize[0] - s->width, + u_ptr += frame->linesize[1] - s->width / 4, + v_ptr += frame->linesize[2] - s->width / 4) { /* reset predictors */ cur_byte = buf[stream_ptr++]; @@ -164,21 +159,10 @@ static int cyuv_decode_frame(AVCodecContext *avctx, } *got_frame = 1; - *(AVFrame*)data= s->frame; return buf_size; } -static av_cold int cyuv_decode_end(AVCodecContext *avctx) -{ - CyuvDecodeContext *s = avctx->priv_data; - - if (s->frame.data[0]) - avctx->release_buffer(avctx, &s->frame); - - return 0; -} - #if CONFIG_AURA_DECODER AVCodec ff_aura_decoder = { .name = "aura", @@ -186,7 +170,6 @@ AVCodec ff_aura_decoder = { .id = AV_CODEC_ID_AURA, .priv_data_size = sizeof(CyuvDecodeContext), .init = cyuv_decode_init, - .close = cyuv_decode_end, .decode = cyuv_decode_frame, .capabilities = CODEC_CAP_DR1, .long_name = NULL_IF_CONFIG_SMALL("Auravision AURA"), @@ -200,7 +183,6 @@ AVCodec ff_cyuv_decoder = { .id = AV_CODEC_ID_CYUV, .priv_data_size = sizeof(CyuvDecodeContext), .init = cyuv_decode_init, - .close = cyuv_decode_end, .decode = cyuv_decode_frame, .capabilities = CODEC_CAP_DR1, .long_name = NULL_IF_CONFIG_SMALL("Creative YUV (CYUV)"), diff --git a/libavcodec/dcadec.c b/libavcodec/dcadec.c index efd07055ec..7a35fcc59d 100644 --- a/libavcodec/dcadec.c +++ b/libavcodec/dcadec.c @@ -1836,7 +1836,7 @@ static int dca_decode_frame(AVCodecContext *avctx, void *data, /* get output buffer */ frame->nb_samples = 256 * (s->sample_blocks / 8); - if ((ret = ff_get_buffer(avctx, frame)) < 0) { + if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } diff --git a/libavcodec/dfa.c b/libavcodec/dfa.c index 119be7066c..bbe4ce2888 100644 --- a/libavcodec/dfa.c +++ b/libavcodec/dfa.c @@ -28,8 +28,6 @@ #include "libavutil/mem.h" typedef struct DfaContext { - AVFrame pic; - uint32_t pal[256]; uint8_t *frame_buf; } DfaContext; @@ -311,6 +309,7 @@ static int dfa_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { + AVFrame *frame = data; DfaContext *s = avctx->priv_data; GetByteContext gb; const uint8_t *buf = avpkt->data; @@ -319,10 +318,7 @@ static int dfa_decode_frame(AVCodecContext *avctx, int ret; int i, pal_elems; - if (s->pic.data[0]) - avctx->release_buffer(avctx, &s->pic); - - if ((ret = ff_get_buffer(avctx, &s->pic))) { + if ((ret = ff_get_buffer(avctx, frame, 0))) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } @@ -340,7 +336,7 @@ static int dfa_decode_frame(AVCodecContext *avctx, s->pal[i] = bytestream2_get_be24(&gb) << 2; s->pal[i] |= (s->pal[i] >> 6) & 0x333; } - s->pic.palette_has_changed = 1; + frame->palette_has_changed = 1; } else if (chunk_type <= 9) { if (decoder[chunk_type - 2](&gb, s->frame_buf, avctx->width, avctx->height)) { av_log(avctx, AV_LOG_ERROR, "Error decoding %s chunk\n", @@ -355,16 +351,15 @@ static int dfa_decode_frame(AVCodecContext *avctx, } buf = s->frame_buf; - dst = s->pic.data[0]; + dst = frame->data[0]; for (i = 0; i < avctx->height; i++) { memcpy(dst, buf, avctx->width); - dst += s->pic.linesize[0]; + dst += frame->linesize[0]; buf += avctx->width; } - memcpy(s->pic.data[1], s->pal, sizeof(s->pal)); + memcpy(frame->data[1], s->pal, sizeof(s->pal)); *got_frame = 1; - *(AVFrame*)data = s->pic; return avpkt->size; } @@ -373,9 +368,6 @@ static av_cold int dfa_decode_end(AVCodecContext *avctx) { DfaContext *s = avctx->priv_data; - if (s->pic.data[0]) - avctx->release_buffer(avctx, &s->pic); - av_freep(&s->frame_buf); return 0; diff --git a/libavcodec/dnxhddec.c b/libavcodec/dnxhddec.c index cc8952b94d..ab6636cbc0 100644 --- a/libavcodec/dnxhddec.c +++ b/libavcodec/dnxhddec.c @@ -34,7 +34,6 @@ typedef struct DNXHDContext { AVCodecContext *avctx; - AVFrame picture; GetBitContext gb; int cid; ///< compression id unsigned int width, height; @@ -63,9 +62,6 @@ static av_cold int dnxhd_decode_init(AVCodecContext *avctx) DNXHDContext *ctx = avctx->priv_data; ctx->avctx = avctx; - avctx->coded_frame = &ctx->picture; - ctx->picture.type = AV_PICTURE_TYPE_I; - ctx->picture.key_frame = 1; return 0; } @@ -100,7 +96,8 @@ static int dnxhd_init_vlc(DNXHDContext *ctx, int cid) return 0; } -static int dnxhd_decode_header(DNXHDContext *ctx, const uint8_t *buf, int buf_size, int first_field) +static int dnxhd_decode_header(DNXHDContext *ctx, AVFrame *frame, + const uint8_t *buf, int buf_size, int first_field) { static const uint8_t header_prefix[] = { 0x00, 0x00, 0x02, 0x80, 0x01 }; int i, cid; @@ -114,8 +111,8 @@ static int dnxhd_decode_header(DNXHDContext *ctx, const uint8_t *buf, int buf_si } if (buf[5] & 2) { /* interlaced */ ctx->cur_field = buf[5] & 1; - ctx->picture.interlaced_frame = 1; - ctx->picture.top_field_first = first_field ^ ctx->cur_field; + frame->interlaced_frame = 1; + frame->top_field_first = first_field ^ ctx->cur_field; av_log(ctx->avctx, AV_LOG_DEBUG, "interlaced %d, cur field %d\n", buf[5] & 3, ctx->cur_field); } @@ -158,11 +155,11 @@ static int dnxhd_decode_header(DNXHDContext *ctx, const uint8_t *buf, int buf_si av_dlog(ctx->avctx, "mb width %d, mb height %d\n", ctx->mb_width, ctx->mb_height); - if ((ctx->height+15)>>4 == ctx->mb_height && ctx->picture.interlaced_frame) + if ((ctx->height+15)>>4 == ctx->mb_height && frame->interlaced_frame) ctx->height <<= 1; if (ctx->mb_height > 68 || - (ctx->mb_height<picture.interlaced_frame) > (ctx->height+15)>>4) { + (ctx->mb_height << frame->interlaced_frame) > (ctx->height+15)>>4) { av_log(ctx->avctx, AV_LOG_ERROR, "mb height too big: %d\n", ctx->mb_height); return -1; } @@ -262,11 +259,11 @@ static void dnxhd_decode_dct_block_10(DNXHDContext *ctx, int16_t *block, dnxhd_decode_dct_block(ctx, block, n, qscale, 6, 8, 4); } -static int dnxhd_decode_macroblock(DNXHDContext *ctx, int x, int y) +static int dnxhd_decode_macroblock(DNXHDContext *ctx, AVFrame *frame, int x, int y) { int shift1 = ctx->bit_depth == 10; - int dct_linesize_luma = ctx->picture.linesize[0]; - int dct_linesize_chroma = ctx->picture.linesize[1]; + int dct_linesize_luma = frame->linesize[0]; + int dct_linesize_chroma = frame->linesize[1]; uint8_t *dest_y, *dest_u, *dest_v; int dct_y_offset, dct_x_offset; int qscale, i; @@ -279,19 +276,19 @@ static int dnxhd_decode_macroblock(DNXHDContext *ctx, int x, int y) ctx->decode_dct_block(ctx, ctx->blocks[i], i, qscale); } - if (ctx->picture.interlaced_frame) { + if (frame->interlaced_frame) { dct_linesize_luma <<= 1; dct_linesize_chroma <<= 1; } - dest_y = ctx->picture.data[0] + ((y * dct_linesize_luma) << 4) + (x << (4 + shift1)); - dest_u = ctx->picture.data[1] + ((y * dct_linesize_chroma) << 4) + (x << (3 + shift1)); - dest_v = ctx->picture.data[2] + ((y * dct_linesize_chroma) << 4) + (x << (3 + shift1)); + dest_y = frame->data[0] + ((y * dct_linesize_luma) << 4) + (x << (4 + shift1)); + dest_u = frame->data[1] + ((y * dct_linesize_chroma) << 4) + (x << (3 + shift1)); + dest_v = frame->data[2] + ((y * dct_linesize_chroma) << 4) + (x << (3 + shift1)); if (ctx->cur_field) { - dest_y += ctx->picture.linesize[0]; - dest_u += ctx->picture.linesize[1]; - dest_v += ctx->picture.linesize[2]; + dest_y += frame->linesize[0]; + dest_u += frame->linesize[1]; + dest_v += frame->linesize[2]; } dct_y_offset = dct_linesize_luma << 3; @@ -312,7 +309,8 @@ static int dnxhd_decode_macroblock(DNXHDContext *ctx, int x, int y) return 0; } -static int dnxhd_decode_macroblocks(DNXHDContext *ctx, const uint8_t *buf, int buf_size) +static int dnxhd_decode_macroblocks(DNXHDContext *ctx, AVFrame *frame, + const uint8_t *buf, int buf_size) { int x, y; for (y = 0; y < ctx->mb_height; y++) { @@ -322,7 +320,7 @@ static int dnxhd_decode_macroblocks(DNXHDContext *ctx, const uint8_t *buf, int b init_get_bits(&ctx->gb, buf + ctx->mb_scan_index[y], (buf_size - ctx->mb_scan_index[y]) << 3); for (x = 0; x < ctx->mb_width; x++) { //START_TIMER; - dnxhd_decode_macroblock(ctx, x, y); + dnxhd_decode_macroblock(ctx, frame, x, y); //STOP_TIMER("decode macroblock"); } } @@ -337,11 +335,12 @@ static int dnxhd_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, DNXHDContext *ctx = avctx->priv_data; AVFrame *picture = data; int first_field = 1; + int ret; av_dlog(avctx, "frame size %d\n", buf_size); decode_coding_unit: - if (dnxhd_decode_header(ctx, buf, buf_size, first_field) < 0) + if (dnxhd_decode_header(ctx, picture, buf, buf_size, first_field) < 0) return -1; if ((avctx->width || avctx->height) && @@ -356,24 +355,23 @@ static int dnxhd_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, avcodec_set_dimensions(avctx, ctx->width, ctx->height); if (first_field) { - if (ctx->picture.data[0]) - avctx->release_buffer(avctx, &ctx->picture); - if (ff_get_buffer(avctx, &ctx->picture) < 0) { + if ((ret = ff_get_buffer(avctx, picture, 0)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); - return -1; + return ret; } + picture->pict_type = AV_PICTURE_TYPE_I; + picture->key_frame = 1; } - dnxhd_decode_macroblocks(ctx, buf + 0x280, buf_size - 0x280); + dnxhd_decode_macroblocks(ctx, picture, buf + 0x280, buf_size - 0x280); - if (first_field && ctx->picture.interlaced_frame) { + if (first_field && picture->interlaced_frame) { buf += ctx->cid_table->coding_unit_size; buf_size -= ctx->cid_table->coding_unit_size; first_field = 0; goto decode_coding_unit; } - *picture = ctx->picture; *got_frame = 1; return buf_size; } @@ -382,8 +380,6 @@ static av_cold int dnxhd_decode_close(AVCodecContext *avctx) { DNXHDContext *ctx = avctx->priv_data; - if (ctx->picture.data[0]) - avctx->release_buffer(avctx, &ctx->picture); ff_free_vlc(&ctx->ac_vlc); ff_free_vlc(&ctx->dc_vlc); ff_free_vlc(&ctx->run_vlc); diff --git a/libavcodec/dpcm.c b/libavcodec/dpcm.c index abf3c84ea9..88b7bd8207 100644 --- a/libavcodec/dpcm.c +++ b/libavcodec/dpcm.c @@ -208,7 +208,7 @@ static int dpcm_decode_frame(AVCodecContext *avctx, void *data, /* get output buffer */ frame->nb_samples = out / avctx->channels; - if ((ret = ff_get_buffer(avctx, frame)) < 0) { + if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } diff --git a/libavcodec/dpx.c b/libavcodec/dpx.c index 0ad17203a0..c1e83046f6 100644 --- a/libavcodec/dpx.c +++ b/libavcodec/dpx.c @@ -25,11 +25,6 @@ #include "avcodec.h" #include "internal.h" -typedef struct DPXContext { - AVFrame picture; -} DPXContext; - - static unsigned int read32(const uint8_t **ptr, int is_big) { unsigned int temp; @@ -58,9 +53,7 @@ static int decode_frame(AVCodecContext *avctx, const uint8_t *buf = avpkt->data; const uint8_t *buf_end = avpkt->data + avpkt->size; int buf_size = avpkt->size; - DPXContext *const s = avctx->priv_data; - AVFrame *picture = data; - AVFrame *const p = &s->picture; + AVFrame *const p = data; uint8_t *ptr; unsigned int offset; @@ -154,13 +147,11 @@ static int decode_frame(AVCodecContext *avctx, return AVERROR_INVALIDDATA; } - if (s->picture.data[0]) - avctx->release_buffer(avctx, &s->picture); if ((ret = av_image_check_size(w, h, 0, avctx)) < 0) return ret; if (w != avctx->width || h != avctx->height) avcodec_set_dimensions(avctx, w, h); - if ((ret = ff_get_buffer(avctx, p)) < 0) { + if ((ret = ff_get_buffer(avctx, p, 0)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } @@ -212,36 +203,15 @@ static int decode_frame(AVCodecContext *avctx, break; } - *picture = s->picture; *got_frame = 1; return buf_size; } -static av_cold int decode_init(AVCodecContext *avctx) -{ - DPXContext *s = avctx->priv_data; - avcodec_get_frame_defaults(&s->picture); - avctx->coded_frame = &s->picture; - return 0; -} - -static av_cold int decode_end(AVCodecContext *avctx) -{ - DPXContext *s = avctx->priv_data; - if (s->picture.data[0]) - avctx->release_buffer(avctx, &s->picture); - - return 0; -} - AVCodec ff_dpx_decoder = { .name = "dpx", .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_DPX, - .priv_data_size = sizeof(DPXContext), - .init = decode_init, - .close = decode_end, .decode = decode_frame, .long_name = NULL_IF_CONFIG_SMALL("DPX image"), .capabilities = CODEC_CAP_DR1, diff --git a/libavcodec/dsicinav.c b/libavcodec/dsicinav.c index 4da7d26670..39479546cc 100644 --- a/libavcodec/dsicinav.c +++ b/libavcodec/dsicinav.c @@ -281,10 +281,9 @@ static int cinvideo_decode_frame(AVCodecContext *avctx, break; } - cin->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE; - if (avctx->reget_buffer(avctx, &cin->frame)) { + if ((res = ff_reget_buffer(avctx, &cin->frame)) < 0) { av_log(cin->avctx, AV_LOG_ERROR, "delphinecinvideo: reget_buffer() failed to allocate a frame\n"); - return -1; + return res; } memcpy(cin->frame.data[1], cin->palette, sizeof(cin->palette)); @@ -296,8 +295,10 @@ static int cinvideo_decode_frame(AVCodecContext *avctx, FFSWAP(uint8_t *, cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_table[CIN_PRE_BMP]); + if ((res = av_frame_ref(data, &cin->frame)) < 0) + return res; + *got_frame = 1; - *(AVFrame *)data = cin->frame; return buf_size; } @@ -307,8 +308,7 @@ static av_cold int cinvideo_decode_end(AVCodecContext *avctx) CinVideoContext *cin = avctx->priv_data; int i; - if (cin->frame.data[0]) - avctx->release_buffer(avctx, &cin->frame); + av_frame_unref(&cin->frame); for (i = 0; i < 3; ++i) av_free(cin->bitmap_table[i]); @@ -341,7 +341,7 @@ static int cinaudio_decode_frame(AVCodecContext *avctx, void *data, /* get output buffer */ frame->nb_samples = avpkt->size - cin->initial_decode_frame; - if ((ret = ff_get_buffer(avctx, frame)) < 0) { + if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } diff --git a/libavcodec/dvdec.c b/libavcodec/dvdec.c index 441deadaab..cc9c232c60 100644 --- a/libavcodec/dvdec.c +++ b/libavcodec/dvdec.c @@ -326,16 +326,12 @@ static int dvvideo_decode_frame(AVCodecContext *avctx, return -1; /* NOTE: we only accept several full frames */ } - if (s->picture.data[0]) - avctx->release_buffer(avctx, &s->picture); - - s->picture.reference = 0; s->picture.key_frame = 1; s->picture.pict_type = AV_PICTURE_TYPE_I; avctx->pix_fmt = s->sys->pix_fmt; avctx->time_base = s->sys->time_base; avcodec_set_dimensions(avctx, s->sys->width, s->sys->height); - if (ff_get_buffer(avctx, &s->picture) < 0) { + if (ff_get_buffer(avctx, &s->picture, 0) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return -1; } @@ -350,7 +346,7 @@ static int dvvideo_decode_frame(AVCodecContext *avctx, /* return image */ *got_frame = 1; - *(AVFrame*)data = s->picture; + av_frame_move_ref(data, &s->picture); /* Determine the codec's sample_aspect ratio from the packet */ vsc_pack = buf + 80*5 + 48 + 5; @@ -367,8 +363,7 @@ static int dvvideo_close(AVCodecContext *c) { DVVideoContext *s = c->priv_data; - if (s->picture.data[0]) - c->release_buffer(c, &s->picture); + av_frame_unref(&s->picture); return 0; } diff --git a/libavcodec/dxa.c b/libavcodec/dxa.c index cfc014a77b..9e7f453b08 100644 --- a/libavcodec/dxa.c +++ b/libavcodec/dxa.c @@ -38,7 +38,7 @@ * Decoder context */ typedef struct DxaDecContext { - AVFrame pic, prev; + AVFrame prev; int dsize; uint8_t *decomp_buf; @@ -48,12 +48,12 @@ typedef struct DxaDecContext { static const int shift1[6] = { 0, 8, 8, 8, 4, 4 }; static const int shift2[6] = { 0, 0, 8, 4, 0, 4 }; -static int decode_13(AVCodecContext *avctx, DxaDecContext *c, uint8_t* dst, uint8_t *src, uint8_t *ref) +static int decode_13(AVCodecContext *avctx, DxaDecContext *c, uint8_t* dst, + int stride, uint8_t *src, uint8_t *ref) { uint8_t *code, *data, *mv, *msk, *tmp, *tmp2; int i, j, k; int type, x, y, d, d2; - int stride = c->pic.linesize[0]; uint32_t mask; code = src + 12; @@ -191,6 +191,7 @@ static int decode_13(AVCodecContext *avctx, DxaDecContext *c, uint8_t* dst, uint static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { + AVFrame *frame = data; const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; DxaDecContext * const c = avctx->priv_data; @@ -216,17 +217,17 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac buf_size -= 768+4; } - if ((ret = ff_get_buffer(avctx, &c->pic)) < 0) { + if ((ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } - memcpy(c->pic.data[1], c->pal, AVPALETTE_SIZE); - c->pic.palette_has_changed = pc; + memcpy(frame->data[1], c->pal, AVPALETTE_SIZE); + frame->palette_has_changed = pc; - outptr = c->pic.data[0]; + outptr = frame->data[0]; srcptr = c->decomp_buf; tmpptr = c->prev.data[0]; - stride = c->pic.linesize[0]; + stride = frame->linesize[0]; if(buf[0]=='N' && buf[1]=='U' && buf[2]=='L' && buf[3]=='L') compr = -1; @@ -240,22 +241,22 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac } switch(compr){ case -1: - c->pic.key_frame = 0; - c->pic.pict_type = AV_PICTURE_TYPE_P; + frame->key_frame = 0; + frame->pict_type = AV_PICTURE_TYPE_P; if(c->prev.data[0]) - memcpy(c->pic.data[0], c->prev.data[0], c->pic.linesize[0] * avctx->height); + memcpy(frame->data[0], c->prev.data[0], frame->linesize[0] * avctx->height); else{ // Should happen only when first frame is 'NULL' - memset(c->pic.data[0], 0, c->pic.linesize[0] * avctx->height); - c->pic.key_frame = 1; - c->pic.pict_type = AV_PICTURE_TYPE_I; + memset(frame->data[0], 0, frame->linesize[0] * avctx->height); + frame->key_frame = 1; + frame->pict_type = AV_PICTURE_TYPE_I; } break; case 2: case 3: case 4: case 5: - c->pic.key_frame = !(compr & 1); - c->pic.pict_type = (compr & 1) ? AV_PICTURE_TYPE_P : AV_PICTURE_TYPE_I; + frame->key_frame = !(compr & 1); + frame->pict_type = (compr & 1) ? AV_PICTURE_TYPE_P : AV_PICTURE_TYPE_I; for(j = 0; j < avctx->height; j++){ if(compr & 1){ for(i = 0; i < avctx->width; i++) @@ -269,21 +270,20 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac break; case 12: // ScummVM coding case 13: - c->pic.key_frame = 0; - c->pic.pict_type = AV_PICTURE_TYPE_P; - decode_13(avctx, c, c->pic.data[0], srcptr, c->prev.data[0]); + frame->key_frame = 0; + frame->pict_type = AV_PICTURE_TYPE_P; + decode_13(avctx, c, frame->data[0], frame->linesize[0], srcptr, c->prev.data[0]); break; default: av_log(avctx, AV_LOG_ERROR, "Unknown/unsupported compression type %d\n", buf[4]); return AVERROR_INVALIDDATA; } - FFSWAP(AVFrame, c->pic, c->prev); - if(c->pic.data[0]) - avctx->release_buffer(avctx, &c->pic); + av_frame_unref(&c->prev); + if ((ret = av_frame_ref(&c->prev, frame)) < 0) + return ret; *got_frame = 1; - *(AVFrame*)data = c->prev; /* always report that the buffer was completely consumed */ return orig_buf_size; @@ -309,10 +309,7 @@ static av_cold int decode_end(AVCodecContext *avctx) DxaDecContext * const c = avctx->priv_data; av_freep(&c->decomp_buf); - if(c->prev.data[0]) - avctx->release_buffer(avctx, &c->prev); - if(c->pic.data[0]) - avctx->release_buffer(avctx, &c->pic); + av_frame_unref(&c->prev); return 0; } diff --git a/libavcodec/dxtory.c b/libavcodec/dxtory.c index 30983f8056..5b44f15d4f 100644 --- a/libavcodec/dxtory.c +++ b/libavcodec/dxtory.c @@ -28,9 +28,6 @@ static av_cold int decode_init(AVCodecContext *avctx) { avctx->pix_fmt = AV_PIX_FMT_YUV420P; - avctx->coded_frame = avcodec_alloc_frame(); - if (!avctx->coded_frame) - return AVERROR(ENOMEM); return 0; } @@ -39,21 +36,17 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { int h, w; - AVFrame *pic = avctx->coded_frame; + AVFrame *pic = data; const uint8_t *src = avpkt->data; uint8_t *Y1, *Y2, *U, *V; int ret; - if (pic->data[0]) - avctx->release_buffer(avctx, pic); - if (avpkt->size < avctx->width * avctx->height * 3 / 2 + 16) { av_log(avctx, AV_LOG_ERROR, "packet too small\n"); return AVERROR_INVALIDDATA; } - pic->reference = 0; - if ((ret = ff_get_buffer(avctx, pic)) < 0) + if ((ret = ff_get_buffer(avctx, pic, 0)) < 0) return ret; pic->pict_type = AV_PICTURE_TYPE_I; @@ -84,28 +77,16 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, } *got_frame = 1; - *(AVFrame*)data = *pic; return avpkt->size; } -static av_cold int decode_close(AVCodecContext *avctx) -{ - AVFrame *pic = avctx->coded_frame; - if (pic->data[0]) - avctx->release_buffer(avctx, pic); - av_freep(&avctx->coded_frame); - - return 0; -} - AVCodec ff_dxtory_decoder = { .name = "dxtory", .long_name = NULL_IF_CONFIG_SMALL("Dxtory"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_DXTORY, .init = decode_init, - .close = decode_close, .decode = decode_frame, .capabilities = CODEC_CAP_DR1, }; diff --git a/libavcodec/dxva2_h264.c b/libavcodec/dxva2_h264.c index cd5084d685..e71d9e36a1 100644 --- a/libavcodec/dxva2_h264.c +++ b/libavcodec/dxva2_h264.c @@ -69,15 +69,15 @@ static void fill_picture_parameters(struct dxva_context *ctx, const H264Context ff_dxva2_get_surface_index(ctx, r), r->long_ref != 0); - if ((r->f.reference & PICT_TOP_FIELD) && r->field_poc[0] != INT_MAX) + if ((r->reference & PICT_TOP_FIELD) && r->field_poc[0] != INT_MAX) pp->FieldOrderCntList[i][0] = r->field_poc[0]; - if ((r->f.reference & PICT_BOTTOM_FIELD) && r->field_poc[1] != INT_MAX) + if ((r->reference & PICT_BOTTOM_FIELD) && r->field_poc[1] != INT_MAX) pp->FieldOrderCntList[i][1] = r->field_poc[1]; pp->FrameNumList[i] = r->long_ref ? r->pic_id : r->frame_num; - if (r->f.reference & PICT_TOP_FIELD) + if (r->reference & PICT_TOP_FIELD) pp->UsedForReferenceFlags |= 1 << (2*i + 0); - if (r->f.reference & PICT_BOTTOM_FIELD) + if (r->reference & PICT_BOTTOM_FIELD) pp->UsedForReferenceFlags |= 1 << (2*i + 1); } else { pp->RefFrameList[i].bPicEntry = 0xff; @@ -230,7 +230,7 @@ static void fill_slice_long(AVCodecContext *avctx, DXVA_Slice_H264_Long *slice, unsigned plane; fill_picture_entry(&slice->RefPicList[list][i], ff_dxva2_get_surface_index(ctx, r), - r->f.reference == PICT_BOTTOM_FIELD); + r->reference == PICT_BOTTOM_FIELD); for (plane = 0; plane < 3; plane++) { int w, o; if (plane == 0 && h->luma_weight_flag[list]) { diff --git a/libavcodec/eacmv.c b/libavcodec/eacmv.c index 0dce066f1e..cf19a85e5a 100644 --- a/libavcodec/eacmv.c +++ b/libavcodec/eacmv.c @@ -36,9 +36,8 @@ typedef struct CmvContext { AVCodecContext *avctx; - AVFrame frame; ///< current - AVFrame last_frame; ///< last - AVFrame last2_frame; ///< second-last + AVFrame *last_frame; ///< last + AVFrame *last2_frame; ///< second-last int width, height; unsigned int palette[AVPALETTE_COUNT]; } CmvContext; @@ -47,16 +46,27 @@ static av_cold int cmv_decode_init(AVCodecContext *avctx){ CmvContext *s = avctx->priv_data; s->avctx = avctx; avctx->pix_fmt = AV_PIX_FMT_PAL8; + + s->last_frame = av_frame_alloc(); + s->last2_frame = av_frame_alloc(); + if (!s->last_frame || !s->last2_frame) { + av_frame_free(&s->last_frame); + av_frame_free(&s->last2_frame); + return AVERROR(ENOMEM); + } + return 0; } -static void cmv_decode_intra(CmvContext * s, const uint8_t *buf, const uint8_t *buf_end){ - unsigned char *dst = s->frame.data[0]; +static void cmv_decode_intra(CmvContext * s, AVFrame *frame, + const uint8_t *buf, const uint8_t *buf_end) +{ + unsigned char *dst = frame->data[0]; int i; for (i=0; i < s->avctx->height && buf_end - buf >= s->avctx->width; i++) { memcpy(dst, buf, s->avctx->width); - dst += s->frame.linesize[0]; + dst += frame->linesize[0]; buf += s->avctx->width; } } @@ -80,7 +90,9 @@ static void cmv_motcomp(unsigned char *dst, int dst_stride, } } -static void cmv_decode_inter(CmvContext * s, const uint8_t *buf, const uint8_t *buf_end){ +static void cmv_decode_inter(CmvContext *s, AVFrame *frame, const uint8_t *buf, + const uint8_t *buf_end) +{ const uint8_t *raw = buf + (s->avctx->width*s->avctx->height/16); int x,y,i; @@ -88,28 +100,28 @@ static void cmv_decode_inter(CmvContext * s, const uint8_t *buf, const uint8_t * for(y=0; yavctx->height/4; y++) for(x=0; xavctx->width/4 && buf_end - buf > i; x++) { if (buf[i]==0xFF) { - unsigned char *dst = s->frame.data[0] + (y*4)*s->frame.linesize[0] + x*4; + unsigned char *dst = frame->data[0] + (y*4)*frame->linesize[0] + x*4; if (raw+16frame.linesize[0], raw+4, 4); - memcpy(dst+2*s->frame.linesize[0], raw+8, 4); - memcpy(dst+3*s->frame.linesize[0], raw+12, 4); + memcpy(dst + frame->linesize[0], raw+4, 4); + memcpy(dst + 2 * frame->linesize[0], raw+8, 4); + memcpy(dst + 3 * frame->linesize[0], raw+12, 4); raw+=16; }else if(raw> 4)) - 7; - if (s->last2_frame.data[0]) - cmv_motcomp(s->frame.data[0], s->frame.linesize[0], - s->last2_frame.data[0], s->last2_frame.linesize[0], + if (s->last2_frame->data[0]) + cmv_motcomp(frame->data[0], frame->linesize[0], + s->last2_frame->data[0], s->last2_frame->linesize[0], x*4, y*4, xoffset, yoffset, s->avctx->width, s->avctx->height); raw++; } }else{ /* inter using last frame as reference */ int xoffset = (buf[i] & 0xF) - 7; int yoffset = ((buf[i] >> 4)) - 7; - cmv_motcomp(s->frame.data[0], s->frame.linesize[0], - s->last_frame.data[0], s->last_frame.linesize[0], + cmv_motcomp(frame->data[0], frame->linesize[0], + s->last_frame->data[0], s->last_frame->linesize[0], x*4, y*4, xoffset, yoffset, s->avctx->width, s->avctx->height); } i++; @@ -154,6 +166,8 @@ static int cmv_decode_frame(AVCodecContext *avctx, int buf_size = avpkt->size; CmvContext *s = avctx->priv_data; const uint8_t *buf_end = buf + buf_size; + AVFrame *frame = data; + int ret; if (buf_end - buf < EA_PREAMBLE_SIZE) return AVERROR_INVALIDDATA; @@ -166,46 +180,39 @@ static int cmv_decode_frame(AVCodecContext *avctx, if (av_image_check_size(s->width, s->height, 0, s->avctx)) return -1; - /* shuffle */ - if (s->last2_frame.data[0]) - avctx->release_buffer(avctx, &s->last2_frame); - FFSWAP(AVFrame, s->last_frame, s->last2_frame); - FFSWAP(AVFrame, s->frame, s->last_frame); - - s->frame.reference = 1; - s->frame.buffer_hints = FF_BUFFER_HINTS_VALID; - if (ff_get_buffer(avctx, &s->frame)<0) { + if ((ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); - return -1; + return ret; } - memcpy(s->frame.data[1], s->palette, AVPALETTE_SIZE); + memcpy(frame->data[1], s->palette, AVPALETTE_SIZE); buf += EA_PREAMBLE_SIZE; if ((buf[0]&1)) { // subtype - cmv_decode_inter(s, buf+2, buf_end); - s->frame.key_frame = 0; - s->frame.pict_type = AV_PICTURE_TYPE_P; + cmv_decode_inter(s, frame, buf+2, buf_end); + frame->key_frame = 0; + frame->pict_type = AV_PICTURE_TYPE_P; }else{ - s->frame.key_frame = 1; - s->frame.pict_type = AV_PICTURE_TYPE_I; - cmv_decode_intra(s, buf+2, buf_end); + frame->key_frame = 1; + frame->pict_type = AV_PICTURE_TYPE_I; + cmv_decode_intra(s, frame, buf+2, buf_end); } + av_frame_unref(s->last2_frame); + av_frame_move_ref(s->last2_frame, s->last_frame); + if ((ret = av_frame_ref(s->last_frame, frame)) < 0) + return ret; + *got_frame = 1; - *(AVFrame*)data = s->frame; return buf_size; } static av_cold int cmv_decode_end(AVCodecContext *avctx){ CmvContext *s = avctx->priv_data; - if (s->frame.data[0]) - s->avctx->release_buffer(avctx, &s->frame); - if (s->last_frame.data[0]) - s->avctx->release_buffer(avctx, &s->last_frame); - if (s->last2_frame.data[0]) - s->avctx->release_buffer(avctx, &s->last2_frame); + + av_frame_free(&s->last_frame); + av_frame_free(&s->last2_frame); return 0; } diff --git a/libavcodec/eamad.c b/libavcodec/eamad.c index f9b43a147b..e666a45360 100644 --- a/libavcodec/eamad.c +++ b/libavcodec/eamad.c @@ -45,7 +45,6 @@ typedef struct MadContext { AVCodecContext *avctx; DSPContext dsp; - AVFrame frame; AVFrame last_frame; GetBitContext gb; void *bitstream_buf; @@ -78,34 +77,36 @@ static inline void comp(unsigned char *dst, int dst_stride, dst[j*dst_stride + i] = av_clip_uint8(src[j*src_stride + i] + add); } -static inline void comp_block(MadContext *t, int mb_x, int mb_y, +static inline void comp_block(MadContext *t, AVFrame *frame, + int mb_x, int mb_y, int j, int mv_x, int mv_y, int add) { if (j < 4) { - comp(t->frame.data[0] + (mb_y*16 + ((j&2)<<2))*t->frame.linesize[0] + mb_x*16 + ((j&1)<<3), - t->frame.linesize[0], + comp(frame->data[0] + (mb_y*16 + ((j&2)<<2))*frame->linesize[0] + mb_x*16 + ((j&1)<<3), + frame->linesize[0], t->last_frame.data[0] + (mb_y*16 + ((j&2)<<2) + mv_y)*t->last_frame.linesize[0] + mb_x*16 + ((j&1)<<3) + mv_x, t->last_frame.linesize[0], add); } else if (!(t->avctx->flags & CODEC_FLAG_GRAY)) { int index = j - 3; - comp(t->frame.data[index] + (mb_y*8)*t->frame.linesize[index] + mb_x * 8, - t->frame.linesize[index], + comp(frame->data[index] + (mb_y*8)*frame->linesize[index] + mb_x * 8, + frame->linesize[index], t->last_frame.data[index] + (mb_y * 8 + (mv_y/2))*t->last_frame.linesize[index] + mb_x * 8 + (mv_x/2), t->last_frame.linesize[index], add); } } -static inline void idct_put(MadContext *t, int16_t *block, int mb_x, int mb_y, int j) +static inline void idct_put(MadContext *t, AVFrame *frame, int16_t *block, + int mb_x, int mb_y, int j) { if (j < 4) { ff_ea_idct_put_c( - t->frame.data[0] + (mb_y*16 + ((j&2)<<2))*t->frame.linesize[0] + mb_x*16 + ((j&1)<<3), - t->frame.linesize[0], block); + frame->data[0] + (mb_y*16 + ((j&2)<<2))*frame->linesize[0] + mb_x*16 + ((j&1)<<3), + frame->linesize[0], block); } else if (!(t->avctx->flags & CODEC_FLAG_GRAY)) { int index = j - 3; ff_ea_idct_put_c( - t->frame.data[index] + (mb_y*8)*t->frame.linesize[index] + mb_x*8, - t->frame.linesize[index], block); + frame->data[index] + (mb_y*8)*frame->linesize[index] + mb_x*8, + frame->linesize[index], block); } } @@ -179,7 +180,7 @@ static int decode_motion(GetBitContext *gb) return value; } -static void decode_mb(MadContext *s, int inter) +static void decode_mb(MadContext *s, AVFrame *frame, int inter) { int mv_map = 0; int mv_x, mv_y; @@ -199,11 +200,11 @@ static void decode_mb(MadContext *s, int inter) for (j=0; j<6; j++) { if (mv_map & (1<gb); - comp_block(s, s->mb_x, s->mb_y, j, mv_x, mv_y, add); + comp_block(s, frame, s->mb_x, s->mb_y, j, mv_x, mv_y, add); } else { s->dsp.clear_block(s->block); decode_block_intra(s, s->block); - idct_put(s, s->block, s->mb_x, s->mb_y, j); + idct_put(s, frame, s->block, s->mb_x, s->mb_y, j); } } } @@ -225,9 +226,10 @@ static int decode_frame(AVCodecContext *avctx, int buf_size = avpkt->size; const uint8_t *buf_end = buf+buf_size; MadContext *s = avctx->priv_data; + AVFrame *frame = data; int width, height; int chunk_type; - int inter; + int inter, ret; if (buf_size < 17) { av_log(avctx, AV_LOG_ERROR, "Input buffer too small\n"); @@ -251,16 +253,12 @@ static int decode_frame(AVCodecContext *avctx, if (av_image_check_size(width, height, 0, avctx) < 0) return -1; avcodec_set_dimensions(avctx, width, height); - if (s->frame.data[0]) - avctx->release_buffer(avctx, &s->frame); + av_frame_unref(&s->last_frame); } - s->frame.reference = 1; - if (!s->frame.data[0]) { - if (ff_get_buffer(avctx, &s->frame) < 0) { - av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); - return -1; - } + if ((ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF)) < 0) { + av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); + return ret; } av_fast_padded_malloc(&s->bitstream_buf, &s->bitstream_buf_size, @@ -272,13 +270,15 @@ static int decode_frame(AVCodecContext *avctx, for (s->mb_y=0; s->mb_y < (avctx->height+15)/16; s->mb_y++) for (s->mb_x=0; s->mb_x < (avctx->width +15)/16; s->mb_x++) - decode_mb(s, inter); + decode_mb(s, frame, inter); *got_frame = 1; - *(AVFrame*)data = s->frame; - if (chunk_type != MADe_TAG) - FFSWAP(AVFrame, s->frame, s->last_frame); + if (chunk_type != MADe_TAG) { + av_frame_unref(&s->last_frame); + if ((ret = av_frame_ref(&s->last_frame, frame)) < 0) + return ret; + } return buf_size; } @@ -286,10 +286,7 @@ static int decode_frame(AVCodecContext *avctx, static av_cold int decode_end(AVCodecContext *avctx) { MadContext *t = avctx->priv_data; - if (t->frame.data[0]) - avctx->release_buffer(avctx, &t->frame); - if (t->last_frame.data[0]) - avctx->release_buffer(avctx, &t->last_frame); + av_frame_unref(&t->last_frame); av_free(t->bitstream_buf); return 0; } diff --git a/libavcodec/eatgq.c b/libavcodec/eatgq.c index a020c52992..9495066eff 100644 --- a/libavcodec/eatgq.c +++ b/libavcodec/eatgq.c @@ -39,7 +39,6 @@ typedef struct TgqContext { AVCodecContext *avctx; - AVFrame frame; int width, height; ScanTable scantable; int qtable[64]; @@ -105,21 +104,21 @@ static void tgq_decode_block(TgqContext *s, int16_t block[64], GetBitContext *gb block[0] += 128 << 4; } -static void tgq_idct_put_mb(TgqContext *s, int16_t (*block)[64], +static void tgq_idct_put_mb(TgqContext *s, int16_t (*block)[64], AVFrame *frame, int mb_x, int mb_y) { - int linesize = s->frame.linesize[0]; - uint8_t *dest_y = s->frame.data[0] + (mb_y * 16 * linesize) + mb_x * 16; - uint8_t *dest_cb = s->frame.data[1] + (mb_y * 8 * s->frame.linesize[1]) + mb_x * 8; - uint8_t *dest_cr = s->frame.data[2] + (mb_y * 8 * s->frame.linesize[2]) + mb_x * 8; + int linesize = frame->linesize[0]; + uint8_t *dest_y = frame->data[0] + (mb_y * 16 * linesize) + mb_x * 16; + uint8_t *dest_cb = frame->data[1] + (mb_y * 8 * frame->linesize[1]) + mb_x * 8; + uint8_t *dest_cr = frame->data[2] + (mb_y * 8 * frame->linesize[2]) + mb_x * 8; ff_ea_idct_put_c(dest_y , linesize, block[0]); ff_ea_idct_put_c(dest_y + 8, linesize, block[1]); ff_ea_idct_put_c(dest_y + 8 * linesize , linesize, block[2]); ff_ea_idct_put_c(dest_y + 8 * linesize + 8, linesize, block[3]); if (!(s->avctx->flags & CODEC_FLAG_GRAY)) { - ff_ea_idct_put_c(dest_cb, s->frame.linesize[1], block[4]); - ff_ea_idct_put_c(dest_cr, s->frame.linesize[2], block[5]); + ff_ea_idct_put_c(dest_cb, frame->linesize[1], block[4]); + ff_ea_idct_put_c(dest_cr, frame->linesize[2], block[5]); } } @@ -132,23 +131,24 @@ static inline void tgq_dconly(TgqContext *s, unsigned char *dst, memset(dst + j * dst_stride, level, 8); } -static void tgq_idct_put_mb_dconly(TgqContext *s, int mb_x, int mb_y, const int8_t *dc) +static void tgq_idct_put_mb_dconly(TgqContext *s, AVFrame *frame, + int mb_x, int mb_y, const int8_t *dc) { - int linesize = s->frame.linesize[0]; - uint8_t *dest_y = s->frame.data[0] + (mb_y * 16 * linesize) + mb_x * 16; - uint8_t *dest_cb = s->frame.data[1] + (mb_y * 8 * s->frame.linesize[1]) + mb_x * 8; - uint8_t *dest_cr = s->frame.data[2] + (mb_y * 8 * s->frame.linesize[2]) + mb_x * 8; + int linesize = frame->linesize[0]; + uint8_t *dest_y = frame->data[0] + (mb_y * 16 * linesize) + mb_x * 16; + uint8_t *dest_cb = frame->data[1] + (mb_y * 8 * frame->linesize[1]) + mb_x * 8; + uint8_t *dest_cr = frame->data[2] + (mb_y * 8 * frame->linesize[2]) + mb_x * 8; tgq_dconly(s, dest_y, linesize, dc[0]); tgq_dconly(s, dest_y + 8, linesize, dc[1]); tgq_dconly(s, dest_y + 8 * linesize, linesize, dc[2]); tgq_dconly(s, dest_y + 8 * linesize + 8, linesize, dc[3]); if (!(s->avctx->flags & CODEC_FLAG_GRAY)) { - tgq_dconly(s, dest_cb, s->frame.linesize[1], dc[4]); - tgq_dconly(s, dest_cr, s->frame.linesize[2], dc[5]); + tgq_dconly(s, dest_cb, frame->linesize[1], dc[4]); + tgq_dconly(s, dest_cr, frame->linesize[2], dc[5]); } } -static void tgq_decode_mb(TgqContext *s, int mb_y, int mb_x) +static void tgq_decode_mb(TgqContext *s, AVFrame *frame, int mb_y, int mb_x) { int mode; int i; @@ -160,7 +160,7 @@ static void tgq_decode_mb(TgqContext *s, int mb_y, int mb_x) init_get_bits(&gb, s->gb.buffer, FFMIN(s->gb.buffer_end - s->gb.buffer, mode) * 8); for (i = 0; i < 6; i++) tgq_decode_block(s, s->block[i], &gb); - tgq_idct_put_mb(s, s->block, mb_x, mb_y); + tgq_idct_put_mb(s, s->block, frame, mb_x, mb_y); bytestream2_skip(&s->gb, mode); } else { if (mode == 3) { @@ -177,7 +177,7 @@ static void tgq_decode_mb(TgqContext *s, int mb_y, int mb_x) } else { av_log(s->avctx, AV_LOG_ERROR, "unsupported mb mode %i\n", mode); } - tgq_idct_put_mb_dconly(s, mb_x, mb_y, dc); + tgq_idct_put_mb_dconly(s, frame, mb_x, mb_y, dc); } } @@ -199,6 +199,7 @@ static int tgq_decode_frame(AVCodecContext *avctx, const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; TgqContext *s = avctx->priv_data; + AVFrame *frame = data; int x, y, ret; int big_endian = AV_RL32(&buf[4]) > 0x000FFFFF; @@ -217,47 +218,32 @@ static int tgq_decode_frame(AVCodecContext *avctx, if (s->avctx->width!=s->width || s->avctx->height!=s->height) { avcodec_set_dimensions(s->avctx, s->width, s->height); - if (s->frame.data[0]) - avctx->release_buffer(avctx, &s->frame); } tgq_calculate_qtable(s, bytestream2_get_byteu(&s->gb)); bytestream2_skip(&s->gb, 3); - if (!s->frame.data[0]) { - s->frame.key_frame = 1; - s->frame.pict_type = AV_PICTURE_TYPE_I; - s->frame.buffer_hints = FF_BUFFER_HINTS_VALID; - if ((ret = ff_get_buffer(avctx, &s->frame)) < 0) { - av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); - return ret; - } + if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) { + av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); + return ret; } + frame->key_frame = 1; + frame->pict_type = AV_PICTURE_TYPE_I; for (y = 0; y < FFALIGN(avctx->height, 16) >> 4; y++) for (x = 0; x < FFALIGN(avctx->width, 16) >> 4; x++) - tgq_decode_mb(s, y, x); + tgq_decode_mb(s, frame, y, x); *got_frame = 1; - *(AVFrame*)data = s->frame; return avpkt->size; } -static av_cold int tgq_decode_end(AVCodecContext *avctx) -{ - TgqContext *s = avctx->priv_data; - if (s->frame.data[0]) - s->avctx->release_buffer(avctx, &s->frame); - return 0; -} - AVCodec ff_eatgq_decoder = { .name = "eatgq", .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_TGQ, .priv_data_size = sizeof(TgqContext), .init = tgq_decode_init, - .close = tgq_decode_end, .decode = tgq_decode_frame, .capabilities = CODEC_CAP_DR1, .long_name = NULL_IF_CONFIG_SMALL("Electronic Arts TGQ video"), diff --git a/libavcodec/eatgv.c b/libavcodec/eatgv.c index 792eaf708e..1e0ec60bc5 100644 --- a/libavcodec/eatgv.c +++ b/libavcodec/eatgv.c @@ -31,6 +31,7 @@ #include "avcodec.h" #define BITSTREAM_READER_LE #include "get_bits.h" +#include "internal.h" #include "libavutil/imgutils.h" #include "libavutil/mem.h" @@ -39,8 +40,8 @@ typedef struct TgvContext { AVCodecContext *avctx; - AVFrame frame; AVFrame last_frame; + uint8_t *frame_buffer; int width,height; uint32_t palette[AVPALETTE_COUNT]; @@ -138,8 +139,8 @@ static int unpack(const uint8_t *src, const uint8_t *src_end, * Decode inter-frame * @return 0 on success, -1 on critical buffer underflow */ -static int tgv_decode_inter(TgvContext *s, const uint8_t *buf, - const uint8_t *buf_end) +static int tgv_decode_inter(TgvContext *s, AVFrame *frame, + const uint8_t *buf, const uint8_t *buf_end) { int num_mvs; int num_blocks_raw; @@ -237,22 +238,13 @@ static int tgv_decode_inter(TgvContext *s, const uint8_t *buf, for (j = 0; j < 4; j++) for (i = 0; i < 4; i++) - s->frame.data[0][(y * 4 + j) * s->frame.linesize[0] + (x * 4 + i)] = + frame->data[0][(y * 4 + j) * frame->linesize[0] + (x * 4 + i)] = src[j * src_stride + i]; } return 0; } -/** release AVFrame buffers if allocated */ -static void cond_release_buffer(AVFrame *pic) -{ - if (pic->data[0]) { - av_freep(&pic->data[0]); - av_free(pic->data[1]); - } -} - static int tgv_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) @@ -261,6 +253,7 @@ static int tgv_decode_frame(AVCodecContext *avctx, int buf_size = avpkt->size; TgvContext *s = avctx->priv_data; const uint8_t *buf_end = buf + buf_size; + AVFrame *frame = data; int chunk_type, ret; chunk_type = AV_RL32(&buf[0]); @@ -277,8 +270,8 @@ static int tgv_decode_frame(AVCodecContext *avctx, s->height = AV_RL16(&buf[2]); if (s->avctx->width != s->width || s->avctx->height != s->height) { avcodec_set_dimensions(s->avctx, s->width, s->height); - cond_release_buffer(&s->frame); - cond_release_buffer(&s->last_frame); + av_freep(&s->frame_buffer); + av_frame_unref(&s->last_frame); } pal_count = AV_RL16(&buf[6]); @@ -292,46 +285,46 @@ static int tgv_decode_frame(AVCodecContext *avctx, if ((ret = av_image_check_size(s->width, s->height, 0, avctx)) < 0) return ret; - /* shuffle */ - FFSWAP(AVFrame, s->frame, s->last_frame); - if (!s->frame.data[0]) { - s->frame.reference = 1; - s->frame.buffer_hints = FF_BUFFER_HINTS_VALID; - s->frame.linesize[0] = s->width; + if ((ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF)) < 0) + return ret; - s->frame.data[0] = av_malloc(s->width * s->height); - if (!s->frame.data[0]) - return AVERROR(ENOMEM); - s->frame.data[1] = av_malloc(AVPALETTE_SIZE); - if (!s->frame.data[1]) { - av_freep(&s->frame.data[0]); - return AVERROR(ENOMEM); - } - } - memcpy(s->frame.data[1], s->palette, AVPALETTE_SIZE); + memcpy(frame->data[1], s->palette, AVPALETTE_SIZE); if (chunk_type == kVGT_TAG) { - s->frame.key_frame = 1; - s->frame.pict_type = AV_PICTURE_TYPE_I; - if (unpack(buf, buf_end, s->frame.data[0], s->avctx->width, s->avctx->height) < 0) { + int y; + frame->key_frame = 1; + frame->pict_type = AV_PICTURE_TYPE_I; + + if (!s->frame_buffer && + !(s->frame_buffer = av_malloc(s->width * s->height))) + return AVERROR(ENOMEM); + + if (unpack(buf, buf_end, s->frame_buffer, s->avctx->width, s->avctx->height) < 0) { av_log(avctx, AV_LOG_WARNING, "truncated intra frame\n"); return AVERROR_INVALIDDATA; } + for (y = 0; y < s->height; y++) + memcpy(frame->data[0] + y * frame->linesize[0], + s->frame_buffer + y * s->width, + s->width); } else { if (!s->last_frame.data[0]) { av_log(avctx, AV_LOG_WARNING, "inter frame without corresponding intra frame\n"); return buf_size; } - s->frame.key_frame = 0; - s->frame.pict_type = AV_PICTURE_TYPE_P; - if (tgv_decode_inter(s, buf, buf_end) < 0) { + frame->key_frame = 0; + frame->pict_type = AV_PICTURE_TYPE_P; + if (tgv_decode_inter(s, frame, buf, buf_end) < 0) { av_log(avctx, AV_LOG_WARNING, "truncated inter frame\n"); return AVERROR_INVALIDDATA; } } + av_frame_unref(&s->last_frame); + if ((ret = av_frame_ref(&s->last_frame, frame)) < 0) + return ret; + *got_frame = 1; - *(AVFrame*)data = s->frame; return buf_size; } @@ -339,8 +332,8 @@ static int tgv_decode_frame(AVCodecContext *avctx, static av_cold int tgv_decode_end(AVCodecContext *avctx) { TgvContext *s = avctx->priv_data; - cond_release_buffer(&s->frame); - cond_release_buffer(&s->last_frame); + av_frame_unref(&s->last_frame); + av_freep(&s->frame_buffer); av_free(s->mv_codebook); av_free(s->block_codebook); return 0; @@ -355,4 +348,5 @@ AVCodec ff_eatgv_decoder = { .close = tgv_decode_end, .decode = tgv_decode_frame, .long_name = NULL_IF_CONFIG_SMALL("Electronic Arts TGV video"), + .capabilities = CODEC_CAP_DR1, }; diff --git a/libavcodec/eatqi.c b/libavcodec/eatqi.c index caf92366e1..eba4b6f390 100644 --- a/libavcodec/eatqi.c +++ b/libavcodec/eatqi.c @@ -36,7 +36,6 @@ typedef struct TqiContext { MpegEncContext s; - AVFrame frame; void *bitstream_buf; unsigned int bitstream_buf_size; DECLARE_ALIGNED(16, int16_t, block)[6][64]; @@ -68,21 +67,21 @@ static int tqi_decode_mb(MpegEncContext *s, int16_t (*block)[64]) return 0; } -static inline void tqi_idct_put(TqiContext *t, int16_t (*block)[64]) +static inline void tqi_idct_put(TqiContext *t, AVFrame *frame, int16_t (*block)[64]) { MpegEncContext *s = &t->s; - int linesize= t->frame.linesize[0]; - uint8_t *dest_y = t->frame.data[0] + (s->mb_y * 16* linesize ) + s->mb_x * 16; - uint8_t *dest_cb = t->frame.data[1] + (s->mb_y * 8 * t->frame.linesize[1]) + s->mb_x * 8; - uint8_t *dest_cr = t->frame.data[2] + (s->mb_y * 8 * t->frame.linesize[2]) + s->mb_x * 8; + int linesize = frame->linesize[0]; + uint8_t *dest_y = frame->data[0] + (s->mb_y * 16* linesize ) + s->mb_x * 16; + uint8_t *dest_cb = frame->data[1] + (s->mb_y * 8 * frame->linesize[1]) + s->mb_x * 8; + uint8_t *dest_cr = frame->data[2] + (s->mb_y * 8 * frame->linesize[2]) + s->mb_x * 8; ff_ea_idct_put_c(dest_y , linesize, block[0]); ff_ea_idct_put_c(dest_y + 8, linesize, block[1]); ff_ea_idct_put_c(dest_y + 8*linesize , linesize, block[2]); ff_ea_idct_put_c(dest_y + 8*linesize + 8, linesize, block[3]); if(!(s->avctx->flags&CODEC_FLAG_GRAY)) { - ff_ea_idct_put_c(dest_cb, t->frame.linesize[1], block[4]); - ff_ea_idct_put_c(dest_cr, t->frame.linesize[2], block[5]); + ff_ea_idct_put_c(dest_cb, frame->linesize[1], block[4]); + ff_ea_idct_put_c(dest_cr, frame->linesize[2], block[5]); } } @@ -104,21 +103,20 @@ static int tqi_decode_frame(AVCodecContext *avctx, const uint8_t *buf_end = buf+buf_size; TqiContext *t = avctx->priv_data; MpegEncContext *s = &t->s; + AVFrame *frame = data; + int ret; s->width = AV_RL16(&buf[0]); s->height = AV_RL16(&buf[2]); tqi_calculate_qtable(s, buf[4]); buf += 8; - if (t->frame.data[0]) - avctx->release_buffer(avctx, &t->frame); - if (s->avctx->width!=s->width || s->avctx->height!=s->height) avcodec_set_dimensions(s->avctx, s->width, s->height); - if(ff_get_buffer(avctx, &t->frame) < 0) { + if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); - return -1; + return ret; } av_fast_padded_malloc(&t->bitstream_buf, &t->bitstream_buf_size, @@ -134,19 +132,16 @@ static int tqi_decode_frame(AVCodecContext *avctx, { if (tqi_decode_mb(s, t->block) < 0) break; - tqi_idct_put(t, t->block); + tqi_idct_put(t, frame, t->block); } *got_frame = 1; - *(AVFrame*)data = t->frame; return buf_size; } static av_cold int tqi_decode_end(AVCodecContext *avctx) { TqiContext *t = avctx->priv_data; - if(t->frame.data[0]) - avctx->release_buffer(avctx, &t->frame); av_free(t->bitstream_buf); return 0; } diff --git a/libavcodec/error_resilience.c b/libavcodec/error_resilience.c index 39892e43b3..78921e3fcf 100644 --- a/libavcodec/error_resilience.c +++ b/libavcodec/error_resilience.c @@ -143,7 +143,7 @@ static void guess_dc(ERContext *s, int16_t *dc, int w, mb_index = (b_x >> is_luma) + (b_y >> is_luma) * s->mb_stride; error = s->error_status_table[mb_index]; - if (IS_INTER(s->cur_pic->f.mb_type[mb_index])) + if (IS_INTER(s->cur_pic->mb_type[mb_index])) continue; // inter if (!(error & ER_DC_ERROR)) continue; // dc-ok @@ -152,7 +152,7 @@ static void guess_dc(ERContext *s, int16_t *dc, int w, for (j = b_x + 1; j < w; j++) { int mb_index_j = (j >> is_luma) + (b_y >> is_luma) * s->mb_stride; int error_j = s->error_status_table[mb_index_j]; - int intra_j = IS_INTRA(s->cur_pic->f.mb_type[mb_index_j]); + int intra_j = IS_INTRA(s->cur_pic->mb_type[mb_index_j]); if (intra_j == 0 || !(error_j & ER_DC_ERROR)) { color[0] = dc[j + b_y * stride]; distance[0] = j - b_x; @@ -164,7 +164,7 @@ static void guess_dc(ERContext *s, int16_t *dc, int w, for (j = b_x - 1; j >= 0; j--) { int mb_index_j = (j >> is_luma) + (b_y >> is_luma) * s->mb_stride; int error_j = s->error_status_table[mb_index_j]; - int intra_j = IS_INTRA(s->cur_pic->f.mb_type[mb_index_j]); + int intra_j = IS_INTRA(s->cur_pic->mb_type[mb_index_j]); if (intra_j == 0 || !(error_j & ER_DC_ERROR)) { color[1] = dc[j + b_y * stride]; distance[1] = b_x - j; @@ -176,7 +176,7 @@ static void guess_dc(ERContext *s, int16_t *dc, int w, for (j = b_y + 1; j < h; j++) { int mb_index_j = (b_x >> is_luma) + (j >> is_luma) * s->mb_stride; int error_j = s->error_status_table[mb_index_j]; - int intra_j = IS_INTRA(s->cur_pic->f.mb_type[mb_index_j]); + int intra_j = IS_INTRA(s->cur_pic->mb_type[mb_index_j]); if (intra_j == 0 || !(error_j & ER_DC_ERROR)) { color[2] = dc[b_x + j * stride]; @@ -189,7 +189,7 @@ static void guess_dc(ERContext *s, int16_t *dc, int w, for (j = b_y - 1; j >= 0; j--) { int mb_index_j = (b_x >> is_luma) + (j >> is_luma) * s->mb_stride; int error_j = s->error_status_table[mb_index_j]; - int intra_j = IS_INTRA(s->cur_pic->f.mb_type[mb_index_j]); + int intra_j = IS_INTRA(s->cur_pic->mb_type[mb_index_j]); if (intra_j == 0 || !(error_j & ER_DC_ERROR)) { color[3] = dc[b_x + j * stride]; distance[3] = b_y - j; @@ -229,13 +229,13 @@ static void h_block_filter(ERContext *s, uint8_t *dst, int w, int y; int left_status = s->error_status_table[( b_x >> is_luma) + (b_y >> is_luma) * s->mb_stride]; int right_status = s->error_status_table[((b_x + 1) >> is_luma) + (b_y >> is_luma) * s->mb_stride]; - int left_intra = IS_INTRA(s->cur_pic->f.mb_type[( b_x >> is_luma) + (b_y >> is_luma) * s->mb_stride]); - int right_intra = IS_INTRA(s->cur_pic->f.mb_type[((b_x + 1) >> is_luma) + (b_y >> is_luma) * s->mb_stride]); + int left_intra = IS_INTRA(s->cur_pic->mb_type[( b_x >> is_luma) + (b_y >> is_luma) * s->mb_stride]); + int right_intra = IS_INTRA(s->cur_pic->mb_type[((b_x + 1) >> is_luma) + (b_y >> is_luma) * s->mb_stride]); int left_damage = left_status & ER_MB_ERROR; int right_damage = right_status & ER_MB_ERROR; int offset = b_x * 8 + b_y * stride * 8; - int16_t *left_mv = s->cur_pic->f.motion_val[0][mvy_stride * b_y + mvx_stride * b_x]; - int16_t *right_mv = s->cur_pic->f.motion_val[0][mvy_stride * b_y + mvx_stride * (b_x + 1)]; + int16_t *left_mv = s->cur_pic->motion_val[0][mvy_stride * b_y + mvx_stride * b_x]; + int16_t *right_mv = s->cur_pic->motion_val[0][mvy_stride * b_y + mvx_stride * (b_x + 1)]; if (!(left_damage || right_damage)) continue; // both undamaged if ((!left_intra) && (!right_intra) && @@ -297,14 +297,14 @@ static void v_block_filter(ERContext *s, uint8_t *dst, int w, int h, int x; int top_status = s->error_status_table[(b_x >> is_luma) + (b_y >> is_luma) * s->mb_stride]; int bottom_status = s->error_status_table[(b_x >> is_luma) + ((b_y + 1) >> is_luma) * s->mb_stride]; - int top_intra = IS_INTRA(s->cur_pic->f.mb_type[(b_x >> is_luma) + ( b_y >> is_luma) * s->mb_stride]); - int bottom_intra = IS_INTRA(s->cur_pic->f.mb_type[(b_x >> is_luma) + ((b_y + 1) >> is_luma) * s->mb_stride]); + int top_intra = IS_INTRA(s->cur_pic->mb_type[(b_x >> is_luma) + ( b_y >> is_luma) * s->mb_stride]); + int bottom_intra = IS_INTRA(s->cur_pic->mb_type[(b_x >> is_luma) + ((b_y + 1) >> is_luma) * s->mb_stride]); int top_damage = top_status & ER_MB_ERROR; int bottom_damage = bottom_status & ER_MB_ERROR; int offset = b_x * 8 + b_y * stride * 8; - int16_t *top_mv = s->cur_pic->f.motion_val[0][mvy_stride * b_y + mvx_stride * b_x]; - int16_t *bottom_mv = s->cur_pic->f.motion_val[0][mvy_stride * (b_y + 1) + mvx_stride * b_x]; + int16_t *top_mv = s->cur_pic->motion_val[0][mvy_stride * b_y + mvx_stride * b_x]; + int16_t *bottom_mv = s->cur_pic->motion_val[0][mvy_stride * (b_y + 1) + mvx_stride * b_x]; if (!(top_damage || bottom_damage)) continue; // both undamaged @@ -369,7 +369,7 @@ static void guess_mv(ERContext *s) int f = 0; int error = s->error_status_table[mb_xy]; - if (IS_INTRA(s->cur_pic->f.mb_type[mb_xy])) + if (IS_INTRA(s->cur_pic->mb_type[mb_xy])) f = MV_FROZEN; // intra // FIXME check if (!(error & ER_MV_ERROR)) f = MV_FROZEN; // inter with undamaged MV @@ -386,7 +386,7 @@ static void guess_mv(ERContext *s) const int mb_xy = mb_x + mb_y * s->mb_stride; int mv_dir = (s->last_pic && s->last_pic->f.data[0]) ? MV_DIR_FORWARD : MV_DIR_BACKWARD; - if (IS_INTRA(s->cur_pic->f.mb_type[mb_xy])) + if (IS_INTRA(s->cur_pic->mb_type[mb_xy])) continue; if (!(s->error_status_table[mb_xy] & ER_MV_ERROR)) continue; @@ -427,7 +427,7 @@ static void guess_mv(ERContext *s) if (fixed[mb_xy] == MV_FROZEN) continue; - assert(!IS_INTRA(s->cur_pic->f.mb_type[mb_xy])); + assert(!IS_INTRA(s->cur_pic->mb_type[mb_xy])); assert(s->last_pic && s->last_pic->f.data[0]); j = 0; @@ -458,38 +458,38 @@ static void guess_mv(ERContext *s) if (mb_x > 0 && fixed[mb_xy - 1]) { mv_predictor[pred_count][0] = - s->cur_pic->f.motion_val[0][mot_index - mot_step][0]; + s->cur_pic->motion_val[0][mot_index - mot_step][0]; mv_predictor[pred_count][1] = - s->cur_pic->f.motion_val[0][mot_index - mot_step][1]; + s->cur_pic->motion_val[0][mot_index - mot_step][1]; ref[pred_count] = - s->cur_pic->f.ref_index[0][4 * (mb_xy - 1)]; + s->cur_pic->ref_index[0][4 * (mb_xy - 1)]; pred_count++; } if (mb_x + 1 < mb_width && fixed[mb_xy + 1]) { mv_predictor[pred_count][0] = - s->cur_pic->f.motion_val[0][mot_index + mot_step][0]; + s->cur_pic->motion_val[0][mot_index + mot_step][0]; mv_predictor[pred_count][1] = - s->cur_pic->f.motion_val[0][mot_index + mot_step][1]; + s->cur_pic->motion_val[0][mot_index + mot_step][1]; ref[pred_count] = - s->cur_pic->f.ref_index[0][4 * (mb_xy + 1)]; + s->cur_pic->ref_index[0][4 * (mb_xy + 1)]; pred_count++; } if (mb_y > 0 && fixed[mb_xy - mb_stride]) { mv_predictor[pred_count][0] = - s->cur_pic->f.motion_val[0][mot_index - mot_stride * mot_step][0]; + s->cur_pic->motion_val[0][mot_index - mot_stride * mot_step][0]; mv_predictor[pred_count][1] = - s->cur_pic->f.motion_val[0][mot_index - mot_stride * mot_step][1]; + s->cur_pic->motion_val[0][mot_index - mot_stride * mot_step][1]; ref[pred_count] = - s->cur_pic->f.ref_index[0][4 * (mb_xy - s->mb_stride)]; + s->cur_pic->ref_index[0][4 * (mb_xy - s->mb_stride)]; pred_count++; } if (mb_y + 1cur_pic->f.motion_val[0][mot_index + mot_stride * mot_step][0]; + s->cur_pic->motion_val[0][mot_index + mot_stride * mot_step][0]; mv_predictor[pred_count][1] = - s->cur_pic->f.motion_val[0][mot_index + mot_stride * mot_step][1]; + s->cur_pic->motion_val[0][mot_index + mot_stride * mot_step][1]; ref[pred_count] = - s->cur_pic->f.ref_index[0][4 * (mb_xy + s->mb_stride)]; + s->cur_pic->ref_index[0][4 * (mb_xy + s->mb_stride)]; pred_count++; } if (pred_count == 0) @@ -547,19 +547,19 @@ skip_mean_and_median: if (s->avctx->codec_id == AV_CODEC_ID_H264) { // FIXME } else { - ff_thread_await_progress(&s->last_pic->f, + ff_thread_await_progress(&s->last_pic->tf, mb_y, 0); } - if (!s->last_pic->f.motion_val[0] || - !s->last_pic->f.ref_index[0]) + if (!s->last_pic->motion_val[0] || + !s->last_pic->ref_index[0]) goto skip_last_mv; - prev_x = s->last_pic->f.motion_val[0][mot_index][0]; - prev_y = s->last_pic->f.motion_val[0][mot_index][1]; - prev_ref = s->last_pic->f.ref_index[0][4 * mb_xy]; + prev_x = s->last_pic->motion_val[0][mot_index][0]; + prev_y = s->last_pic->motion_val[0][mot_index][1]; + prev_ref = s->last_pic->ref_index[0][4 * mb_xy]; } else { - prev_x = s->cur_pic->f.motion_val[0][mot_index][0]; - prev_y = s->cur_pic->f.motion_val[0][mot_index][1]; - prev_ref = s->cur_pic->f.ref_index[0][4 * mb_xy]; + prev_x = s->cur_pic->motion_val[0][mot_index][0]; + prev_y = s->cur_pic->motion_val[0][mot_index][1]; + prev_ref = s->cur_pic->ref_index[0][4 * mb_xy]; } /* last MV */ @@ -576,9 +576,9 @@ skip_last_mv: uint8_t *src = s->cur_pic->f.data[0] + mb_x * 16 + mb_y * 16 * linesize[0]; - s->cur_pic->f.motion_val[0][mot_index][0] = + s->cur_pic->motion_val[0][mot_index][0] = s->mv[0][0][0] = mv_predictor[j][0]; - s->cur_pic->f.motion_val[0][mot_index][1] = + s->cur_pic->motion_val[0][mot_index][1] = s->mv[0][0][1] = mv_predictor[j][1]; // predictor intra or otherwise not available @@ -623,8 +623,8 @@ skip_last_mv: for (i = 0; i < mot_step; i++) for (j = 0; j < mot_step; j++) { - s->cur_pic->f.motion_val[0][mot_index + i + j * mot_stride][0] = s->mv[0][0][0]; - s->cur_pic->f.motion_val[0][mot_index + i + j * mot_stride][1] = s->mv[0][0][1]; + s->cur_pic->motion_val[0][mot_index + i + j * mot_stride][0] = s->mv[0][0][0]; + s->cur_pic->motion_val[0][mot_index + i + j * mot_stride][1] = s->mv[0][0][1]; } s->decode_mb(s->opaque, ref[best_pred], MV_DIR_FORWARD, @@ -706,7 +706,7 @@ static int is_intra_more_likely(ERContext *s) if (s->avctx->codec_id == AV_CODEC_ID_H264) { // FIXME } else { - ff_thread_await_progress(&s->last_pic->f, mb_y, 0); + ff_thread_await_progress(&s->last_pic->tf, mb_y, 0); } is_intra_likely += s->dsp->sad[0](NULL, last_mb_ptr, mb_ptr, linesize[0], 16); @@ -714,7 +714,7 @@ static int is_intra_more_likely(ERContext *s) last_mb_ptr + linesize[0] * 16, linesize[0], 16); } else { - if (IS_INTRA(s->cur_pic->f.mb_type[mb_xy])) + if (IS_INTRA(s->cur_pic->mb_type[mb_xy])) is_intra_likely++; else is_intra_likely--; @@ -831,13 +831,25 @@ void ff_er_frame_end(ERContext *s) return; }; - if (s->cur_pic->f.motion_val[0] == NULL) { + if (s->cur_pic->motion_val[0] == NULL) { av_log(s->avctx, AV_LOG_ERROR, "Warning MVs not available\n"); for (i = 0; i < 2; i++) { - s->cur_pic->f.ref_index[i] = av_mallocz(s->mb_stride * s->mb_height * 4 * sizeof(uint8_t)); - s->cur_pic->motion_val_base[i] = av_mallocz((size + 4) * 2 * sizeof(uint16_t)); - s->cur_pic->f.motion_val[i] = s->cur_pic->motion_val_base[i] + 4; + s->cur_pic->ref_index_buf[i] = av_buffer_allocz(s->mb_stride * s->mb_height * 4 * sizeof(uint8_t)); + s->cur_pic->motion_val_buf[i] = av_buffer_allocz((size + 4) * 2 * sizeof(uint16_t)); + if (!s->cur_pic->ref_index_buf[i] || !s->cur_pic->motion_val_buf[i]) + break; + s->cur_pic->ref_index[i] = s->cur_pic->ref_index_buf[i]->data; + s->cur_pic->motion_val[i] = (int16_t (*)[2])s->cur_pic->motion_val_buf[i]->data + 4; + } + if (i < 2) { + for (i = 0; i < 2; i++) { + av_buffer_unref(&s->cur_pic->ref_index_buf[i]); + av_buffer_unref(&s->cur_pic->motion_val_buf[i]); + s->cur_pic->ref_index[i] = NULL; + s->cur_pic->motion_val[i] = NULL; + } + return; } s->cur_pic->f.motion_subsample_log2 = 3; } @@ -997,9 +1009,9 @@ void ff_er_frame_end(ERContext *s) continue; if (is_intra_likely) - s->cur_pic->f.mb_type[mb_xy] = MB_TYPE_INTRA4x4; + s->cur_pic->mb_type[mb_xy] = MB_TYPE_INTRA4x4; else - s->cur_pic->f.mb_type[mb_xy] = MB_TYPE_16x16 | MB_TYPE_L0; + s->cur_pic->mb_type[mb_xy] = MB_TYPE_16x16 | MB_TYPE_L0; } // change inter to intra blocks if no reference frames are available @@ -1007,15 +1019,15 @@ void ff_er_frame_end(ERContext *s) !(s->next_pic && s->next_pic->f.data[0])) for (i = 0; i < s->mb_num; i++) { const int mb_xy = s->mb_index2xy[i]; - if (!IS_INTRA(s->cur_pic->f.mb_type[mb_xy])) - s->cur_pic->f.mb_type[mb_xy] = MB_TYPE_INTRA4x4; + if (!IS_INTRA(s->cur_pic->mb_type[mb_xy])) + s->cur_pic->mb_type[mb_xy] = MB_TYPE_INTRA4x4; } /* handle inter blocks with damaged AC */ for (mb_y = 0; mb_y < s->mb_height; mb_y++) { for (mb_x = 0; mb_x < s->mb_width; mb_x++) { const int mb_xy = mb_x + mb_y * s->mb_stride; - const int mb_type = s->cur_pic->f.mb_type[mb_xy]; + const int mb_type = s->cur_pic->mb_type[mb_xy]; const int dir = !(s->last_pic && s->last_pic->f.data[0]); const int mv_dir = dir ? MV_DIR_BACKWARD : MV_DIR_FORWARD; int mv_type; @@ -1034,13 +1046,13 @@ void ff_er_frame_end(ERContext *s) int j; mv_type = MV_TYPE_8X8; for (j = 0; j < 4; j++) { - s->mv[0][j][0] = s->cur_pic->f.motion_val[dir][mb_index + (j & 1) + (j >> 1) * s->b8_stride][0]; - s->mv[0][j][1] = s->cur_pic->f.motion_val[dir][mb_index + (j & 1) + (j >> 1) * s->b8_stride][1]; + s->mv[0][j][0] = s->cur_pic->motion_val[dir][mb_index + (j & 1) + (j >> 1) * s->b8_stride][0]; + s->mv[0][j][1] = s->cur_pic->motion_val[dir][mb_index + (j & 1) + (j >> 1) * s->b8_stride][1]; } } else { mv_type = MV_TYPE_16X16; - s->mv[0][0][0] = s->cur_pic->f.motion_val[dir][mb_x * 2 + mb_y * 2 * s->b8_stride][0]; - s->mv[0][0][1] = s->cur_pic->f.motion_val[dir][mb_x * 2 + mb_y * 2 * s->b8_stride][1]; + s->mv[0][0][0] = s->cur_pic->motion_val[dir][mb_x * 2 + mb_y * 2 * s->b8_stride][0]; + s->mv[0][0][1] = s->cur_pic->motion_val[dir][mb_x * 2 + mb_y * 2 * s->b8_stride][1]; } s->decode_mb(s->opaque, 0 /* FIXME h264 partitioned slices need this set */, @@ -1054,7 +1066,7 @@ void ff_er_frame_end(ERContext *s) for (mb_x = 0; mb_x < s->mb_width; mb_x++) { int xy = mb_x * 2 + mb_y * 2 * s->b8_stride; const int mb_xy = mb_x + mb_y * s->mb_stride; - const int mb_type = s->cur_pic->f.mb_type[mb_xy]; + const int mb_type = s->cur_pic->mb_type[mb_xy]; int mv_dir = MV_DIR_FORWARD | MV_DIR_BACKWARD; error = s->error_status_table[mb_xy]; @@ -1075,12 +1087,12 @@ void ff_er_frame_end(ERContext *s) int time_pp = s->pp_time; int time_pb = s->pb_time; - ff_thread_await_progress(&s->next_pic->f, mb_y, 0); + ff_thread_await_progress(&s->next_pic->tf, mb_y, 0); - s->mv[0][0][0] = s->next_pic->f.motion_val[0][xy][0] * time_pb / time_pp; - s->mv[0][0][1] = s->next_pic->f.motion_val[0][xy][1] * time_pb / time_pp; - s->mv[1][0][0] = s->next_pic->f.motion_val[0][xy][0] * (time_pb - time_pp) / time_pp; - s->mv[1][0][1] = s->next_pic->f.motion_val[0][xy][1] * (time_pb - time_pp) / time_pp; + s->mv[0][0][0] = s->next_pic->motion_val[0][xy][0] * time_pb / time_pp; + s->mv[0][0][1] = s->next_pic->motion_val[0][xy][1] * time_pb / time_pp; + s->mv[1][0][0] = s->next_pic->motion_val[0][xy][0] * (time_pb - time_pp) / time_pp; + s->mv[1][0][1] = s->next_pic->motion_val[0][xy][1] * (time_pb - time_pp) / time_pp; } else { s->mv[0][0][0] = 0; s->mv[0][0][1] = 0; @@ -1105,7 +1117,7 @@ void ff_er_frame_end(ERContext *s) int16_t *dc_ptr; uint8_t *dest_y, *dest_cb, *dest_cr; const int mb_xy = mb_x + mb_y * s->mb_stride; - const int mb_type = s->cur_pic->f.mb_type[mb_xy]; + const int mb_type = s->cur_pic->mb_type[mb_xy]; error = s->error_status_table[mb_xy]; @@ -1156,7 +1168,7 @@ void ff_er_frame_end(ERContext *s) for (mb_x = 0; mb_x < s->mb_width; mb_x++) { uint8_t *dest_y, *dest_cb, *dest_cr; const int mb_xy = mb_x + mb_y * s->mb_stride; - const int mb_type = s->cur_pic->f.mb_type[mb_xy]; + const int mb_type = s->cur_pic->mb_type[mb_xy]; error = s->error_status_table[mb_xy]; diff --git a/libavcodec/escape124.c b/libavcodec/escape124.c index a27ab6890d..b304dd8b39 100644 --- a/libavcodec/escape124.c +++ b/libavcodec/escape124.c @@ -78,8 +78,7 @@ static av_cold int escape124_decode_close(AVCodecContext *avctx) for (i = 0; i < 3; i++) av_free(s->codebooks[i].blocks); - if (s->frame.data[0]) - avctx->release_buffer(avctx, &s->frame); + av_frame_unref(&s->frame); return 0; } @@ -203,6 +202,7 @@ static int escape124_decode_frame(AVCodecContext *avctx, const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; Escape124Context *s = avctx->priv_data; + AVFrame *frame = data; GetBitContext gb; unsigned frame_flags, frame_size; @@ -214,8 +214,7 @@ static int escape124_decode_frame(AVCodecContext *avctx, uint16_t* old_frame_data, *new_frame_data; unsigned old_stride, new_stride; - - AVFrame new_frame = { { 0 } }; + int ret; init_get_bits(&gb, buf, buf_size * 8); @@ -230,10 +229,14 @@ static int escape124_decode_frame(AVCodecContext *avctx, // Leave last frame unchanged // FIXME: Is this necessary? I haven't seen it in any real samples if (!(frame_flags & 0x114) || !(frame_flags & 0x7800000)) { + if (!s->frame.data[0]) + return AVERROR_INVALIDDATA; + av_log(NULL, AV_LOG_DEBUG, "Skipping frame\n"); *got_frame = 1; - *(AVFrame*)data = s->frame; + if ((ret = av_frame_ref(frame, &s->frame)) < 0) + return ret; return frame_size; } @@ -266,14 +269,13 @@ static int escape124_decode_frame(AVCodecContext *avctx, } } - new_frame.reference = 3; - if (ff_get_buffer(avctx, &new_frame)) { + if ((ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); - return -1; + return ret; } - new_frame_data = (uint16_t*)new_frame.data[0]; - new_stride = new_frame.linesize[0] / 2; + new_frame_data = (uint16_t*)frame->data[0]; + new_stride = frame->linesize[0] / 2; old_frame_data = (uint16_t*)s->frame.data[0]; old_stride = s->frame.linesize[0] / 2; @@ -354,10 +356,10 @@ static int escape124_decode_frame(AVCodecContext *avctx, "Escape sizes: %i, %i, %i\n", frame_size, buf_size, get_bits_count(&gb) / 8); - if (s->frame.data[0]) - avctx->release_buffer(avctx, &s->frame); + av_frame_unref(&s->frame); + if ((ret = av_frame_ref(&s->frame, frame)) < 0) + return ret; - *(AVFrame*)data = s->frame = new_frame; *got_frame = 1; return frame_size; diff --git a/libavcodec/ffv1.c b/libavcodec/ffv1.c index d37230c6c1..81c684c2fe 100644 --- a/libavcodec/ffv1.c +++ b/libavcodec/ffv1.c @@ -266,10 +266,7 @@ av_cold int ffv1_close(AVCodecContext *avctx) FFV1Context *s = avctx->priv_data; int i, j; - if (avctx->codec->decode && s->picture.data[0]) - avctx->release_buffer(avctx, &s->picture); - if (avctx->codec->decode && s->last_picture.data[0]) - avctx->release_buffer(avctx, &s->last_picture); + av_frame_unref(&s->last_picture); for (j = 0; j < s->slice_count; j++) { FFV1Context *fs = s->slice_context[j]; diff --git a/libavcodec/ffv1.h b/libavcodec/ffv1.h index 4752cea951..43c96079ae 100644 --- a/libavcodec/ffv1.h +++ b/libavcodec/ffv1.h @@ -80,6 +80,8 @@ typedef struct FFV1Context { int flags; int picture_number; AVFrame picture, last_picture; + + AVFrame *cur; int plane_count; int ac; // 1 = range coder <-> 0 = golomb rice int ac_byte_count; // number of bytes used for AC coding diff --git a/libavcodec/ffv1dec.c b/libavcodec/ffv1dec.c index a1b3db360c..f9b094dab7 100644 --- a/libavcodec/ffv1dec.c +++ b/libavcodec/ffv1dec.c @@ -316,16 +316,16 @@ static int decode_slice_header(FFV1Context *f, FFV1Context *fs) ps = get_symbol(c, state, 0); if (ps == 1) { - f->picture.interlaced_frame = 1; - f->picture.top_field_first = 1; + f->cur->interlaced_frame = 1; + f->cur->top_field_first = 1; } else if (ps == 2) { - f->picture.interlaced_frame = 1; - f->picture.top_field_first = 0; + f->cur->interlaced_frame = 1; + f->cur->top_field_first = 0; } else if (ps == 3) { - f->picture.interlaced_frame = 0; + f->cur->interlaced_frame = 0; } - f->picture.sample_aspect_ratio.num = get_symbol(c, state, 0); - f->picture.sample_aspect_ratio.den = get_symbol(c, state, 0); + f->cur->sample_aspect_ratio.num = get_symbol(c, state, 0); + f->cur->sample_aspect_ratio.den = get_symbol(c, state, 0); return 0; } @@ -338,7 +338,7 @@ static int decode_slice(AVCodecContext *c, void *arg) const int ps = (av_pix_fmt_desc_get(c->pix_fmt)->flags & PIX_FMT_PLANAR) ? (c->bits_per_raw_sample > 8) + 1 : 4; - AVFrame *const p = &f->picture; + AVFrame *const p = f->cur; if (f->version > 2) { if (decode_slice_header(f, fs) < 0) { @@ -348,7 +348,7 @@ static int decode_slice(AVCodecContext *c, void *arg) } if ((ret = ffv1_init_slice_state(f, fs)) < 0) return ret; - if (f->picture.key_frame) + if (f->cur->key_frame) ffv1_clear_slice_state(f, fs); width = fs->slice_width; height = fs->slice_height; @@ -799,16 +799,12 @@ static int ffv1_decode_frame(AVCodecContext *avctx, void *data, int buf_size = avpkt->size; FFV1Context *f = avctx->priv_data; RangeCoder *const c = &f->slice_context[0]->c; - AVFrame *const p = &f->picture; int i, ret; uint8_t keystate = 128; const uint8_t *buf_p; + AVFrame *const p = data; - AVFrame *picture = data; - - /* release previously stored data */ - if (p->data[0]) - avctx->release_buffer(avctx, p); + f->cur = p; ff_init_range_decoder(c, buf, buf_size); ff_build_rac_states(c, 0.05 * (1LL << 32), 256 - 8); @@ -829,8 +825,7 @@ static int ffv1_decode_frame(AVCodecContext *avctx, void *data, p->key_frame = 0; } - p->reference = 3; //for error concealment - if ((ret = ff_get_buffer(avctx, p)) < 0) { + if ((ret = ff_get_buffer(avctx, p, AV_GET_BUFFER_FLAG_REF)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } @@ -869,6 +864,8 @@ static int ffv1_decode_frame(AVCodecContext *avctx, void *data, ff_init_range_decoder(&fs->c, buf_p, v); } else fs->c.bytestream_end = (uint8_t *)(buf_p + v); + + fs->cur = p; } avctx->execute(avctx, decode_slice, &f->slice_context[0], NULL, @@ -884,13 +881,13 @@ static int ffv1_decode_frame(AVCodecContext *avctx, void *data, 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; - dst[j] = f->picture.data[j] + f->picture.linesize[j] * + dst[j] = p->data[j] + p->linesize[j] * (fs->slice_y >> sv) + (fs->slice_x >> sh); src[j] = f->last_picture.data[j] + f->last_picture.linesize[j] * (fs->slice_y >> sv) + (fs->slice_x >> sh); } - av_image_copy(dst, f->picture.linesize, (const uint8_t **)src, + av_image_copy(dst, p->linesize, (const uint8_t **)src, f->last_picture.linesize, avctx->pix_fmt, fs->slice_width, fs->slice_height); @@ -899,10 +896,12 @@ static int ffv1_decode_frame(AVCodecContext *avctx, void *data, f->picture_number++; - *picture = *p; - *got_frame = 1; + av_frame_unref(&f->last_picture); + if ((ret = av_frame_ref(&f->last_picture, p)) < 0) + return ret; + f->cur = NULL; - FFSWAP(AVFrame, f->picture, f->last_picture); + *got_frame = 1; return buf_size; } diff --git a/libavcodec/flacdec.c b/libavcodec/flacdec.c index 6bb6be3477..91412ef821 100644 --- a/libavcodec/flacdec.c +++ b/libavcodec/flacdec.c @@ -529,7 +529,7 @@ static int flac_decode_frame(AVCodecContext *avctx, void *data, /* get output buffer */ frame->nb_samples = s->blocksize; - if ((ret = ff_get_buffer(avctx, frame)) < 0) { + if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } diff --git a/libavcodec/flashsv.c b/libavcodec/flashsv.c index 3c5a35c0dd..3f211926e3 100644 --- a/libavcodec/flashsv.c +++ b/libavcodec/flashsv.c @@ -41,6 +41,7 @@ #include "avcodec.h" #include "bytestream.h" #include "get_bits.h" +#include "internal.h" typedef struct BlockInfo { uint8_t *pos; @@ -238,7 +239,7 @@ static int flashsv_decode_frame(AVCodecContext *avctx, void *data, { int buf_size = avpkt->size; FlashSVContext *s = avctx->priv_data; - int h_blocks, v_blocks, h_part, v_part, i, j; + int h_blocks, v_blocks, h_part, v_part, i, j, ret; GetBitContext gb; /* no supplementary picture */ @@ -327,13 +328,9 @@ static int flashsv_decode_frame(AVCodecContext *avctx, void *data, s->image_width, s->image_height, s->block_width, s->block_height, h_blocks, v_blocks, h_part, v_part); - s->frame.reference = 3; - s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | - FF_BUFFER_HINTS_PRESERVE | - FF_BUFFER_HINTS_REUSABLE; - if (avctx->reget_buffer(avctx, &s->frame) < 0) { + if ((ret = ff_reget_buffer(avctx, &s->frame)) < 0) { av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); - return -1; + return ret; } /* loop over all block columns */ @@ -358,8 +355,7 @@ static int flashsv_decode_frame(AVCodecContext *avctx, void *data, s->diff_height = cur_blk_height; if (8 * size > get_bits_left(&gb)) { - avctx->release_buffer(avctx, &s->frame); - s->frame.data[0] = NULL; + av_frame_unref(&s->frame); return AVERROR_INVALIDDATA; } @@ -441,8 +437,10 @@ static int flashsv_decode_frame(AVCodecContext *avctx, void *data, memcpy(s->keyframe, s->frame.data[0], s->frame.linesize[0] * avctx->height); } + if ((ret = av_frame_ref(data, &s->frame)) < 0) + return ret; + *got_frame = 1; - *(AVFrame*)data = s->frame; if ((get_bits_count(&gb) / 8) != buf_size) av_log(avctx, AV_LOG_ERROR, "buffer not fully consumed (%d != %d)\n", @@ -458,8 +456,7 @@ static av_cold int flashsv_decode_end(AVCodecContext *avctx) FlashSVContext *s = avctx->priv_data; inflateEnd(&s->zstream); /* release the frame if needed */ - if (s->frame.data[0]) - avctx->release_buffer(avctx, &s->frame); + av_frame_unref(&s->frame); /* free the tmpblock */ av_free(s->tmpblock); diff --git a/libavcodec/flicvideo.c b/libavcodec/flicvideo.c index 08c3ef32a8..2588619e15 100644 --- a/libavcodec/flicvideo.c +++ b/libavcodec/flicvideo.c @@ -42,6 +42,7 @@ #include "libavutil/intreadwrite.h" #include "avcodec.h" #include "bytestream.h" +#include "internal.h" #include "mathops.h" #define FLI_256_COLOR 4 @@ -167,9 +168,7 @@ static int flic_decode_frame_8BPP(AVCodecContext *avctx, bytestream2_init(&g2, buf, buf_size); - s->frame.reference = 1; - s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE; - if ((ret = avctx->reget_buffer(avctx, &s->frame)) < 0) { + if ((ret = ff_reget_buffer(avctx, &s->frame)) < 0) { av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); return ret; } @@ -424,8 +423,10 @@ static int flic_decode_frame_8BPP(AVCodecContext *avctx, s->new_palette = 0; } + if ((ret = av_frame_ref(data, &s->frame)) < 0) + return ret; + *got_frame = 1; - *(AVFrame*)data = s->frame; return buf_size; } @@ -463,9 +464,7 @@ static int flic_decode_frame_15_16BPP(AVCodecContext *avctx, bytestream2_init(&g2, buf, buf_size); - s->frame.reference = 1; - s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE; - if ((ret = avctx->reget_buffer(avctx, &s->frame)) < 0) { + if ((ret = ff_reget_buffer(avctx, &s->frame)) < 0) { av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); return ret; } @@ -685,9 +684,10 @@ static int flic_decode_frame_15_16BPP(AVCodecContext *avctx, av_log(avctx, AV_LOG_ERROR, "Processed FLI chunk where chunk size = %d " \ "and final chunk ptr = %d\n", buf_size, bytestream2_tell(&g2)); + if ((ret = av_frame_ref(data, &s->frame)) < 0) + return ret; *got_frame = 1; - *(AVFrame*)data = s->frame; return buf_size; } @@ -733,8 +733,7 @@ static av_cold int flic_decode_end(AVCodecContext *avctx) { FlicDecodeContext *s = avctx->priv_data; - if (s->frame.data[0]) - avctx->release_buffer(avctx, &s->frame); + av_frame_unref(&s->frame); return 0; } diff --git a/libavcodec/fraps.c b/libavcodec/fraps.c index 237cb743f9..2a5a5a8b38 100644 --- a/libavcodec/fraps.c +++ b/libavcodec/fraps.c @@ -36,6 +36,7 @@ #include "huffman.h" #include "bytestream.h" #include "dsputil.h" +#include "internal.h" #define FPS_TAG MKTAG('F', 'P', 'S', 'x') @@ -60,7 +61,6 @@ static av_cold int decode_init(AVCodecContext *avctx) { FrapsContext * const s = avctx->priv_data; - avctx->coded_frame = &s->frame; avctx->pix_fmt = AV_PIX_FMT_NONE; /* set in decode_frame */ s->avctx = avctx; @@ -161,7 +161,7 @@ static int decode_frame(AVCodecContext *avctx, pix_fmt = version & 1 ? AV_PIX_FMT_BGR24 : AV_PIX_FMT_YUVJ420P; if (avctx->pix_fmt != pix_fmt && f->data[0]) { - avctx->release_buffer(avctx, f); + av_frame_unref(f); } avctx->pix_fmt = pix_fmt; @@ -184,11 +184,7 @@ static int decode_frame(AVCodecContext *avctx, return AVERROR_INVALIDDATA; } - f->reference = 1; - f->buffer_hints = FF_BUFFER_HINTS_VALID | - FF_BUFFER_HINTS_PRESERVE | - FF_BUFFER_HINTS_REUSABLE; - if ((ret = avctx->reget_buffer(avctx, f)) < 0) { + if ((ret = ff_reget_buffer(avctx, f)) < 0) { av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); return ret; } @@ -225,11 +221,7 @@ static int decode_frame(AVCodecContext *avctx, return AVERROR_INVALIDDATA; } - f->reference = 1; - f->buffer_hints = FF_BUFFER_HINTS_VALID | - FF_BUFFER_HINTS_PRESERVE | - FF_BUFFER_HINTS_REUSABLE; - if ((ret = avctx->reget_buffer(avctx, f)) < 0) { + if ((ret = ff_reget_buffer(avctx, f)) < 0) { av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); return ret; } @@ -252,11 +244,7 @@ static int decode_frame(AVCodecContext *avctx, * Fraps v4 is virtually the same */ planes = 3; - f->reference = 1; - f->buffer_hints = FF_BUFFER_HINTS_VALID | - FF_BUFFER_HINTS_PRESERVE | - FF_BUFFER_HINTS_REUSABLE; - if ((ret = avctx->reget_buffer(avctx, f)) < 0) { + if ((ret = ff_reget_buffer(avctx, f)) < 0) { av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); return ret; } @@ -300,11 +288,7 @@ static int decode_frame(AVCodecContext *avctx, case 5: /* Virtually the same as version 4, but is for RGB24 */ planes = 3; - f->reference = 1; - f->buffer_hints = FF_BUFFER_HINTS_VALID | - FF_BUFFER_HINTS_PRESERVE | - FF_BUFFER_HINTS_REUSABLE; - if ((ret = avctx->reget_buffer(avctx, f)) < 0) { + if ((ret = ff_reget_buffer(avctx, f)) < 0) { av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); return ret; } @@ -350,7 +334,8 @@ static int decode_frame(AVCodecContext *avctx, break; } - *frame = *f; + if ((ret = av_frame_ref(frame, f)) < 0) + return ret; *got_frame = 1; return buf_size; @@ -366,8 +351,7 @@ static av_cold int decode_end(AVCodecContext *avctx) { FrapsContext *s = (FrapsContext*)avctx->priv_data; - if (s->frame.data[0]) - avctx->release_buffer(avctx, &s->frame); + av_frame_unref(&s->frame); av_freep(&s->tmpbuf); return 0; diff --git a/libavcodec/frwu.c b/libavcodec/frwu.c index 3f8f6baf6a..1323727b42 100644 --- a/libavcodec/frwu.c +++ b/libavcodec/frwu.c @@ -32,10 +32,6 @@ static av_cold int decode_init(AVCodecContext *avctx) } avctx->pix_fmt = AV_PIX_FMT_UYVY422; - avctx->coded_frame = avcodec_alloc_frame(); - if (!avctx->coded_frame) - return AVERROR(ENOMEM); - return 0; } @@ -43,13 +39,10 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { int field, ret; - AVFrame *pic = avctx->coded_frame; + AVFrame *pic = data; const uint8_t *buf = avpkt->data; const uint8_t *buf_end = buf + avpkt->size; - if (pic->data[0]) - avctx->release_buffer(avctx, pic); - if (avpkt->size < avctx->width * 2 * avctx->height + 4 + 2*8) { av_log(avctx, AV_LOG_ERROR, "Packet is too small.\n"); return AVERROR_INVALIDDATA; @@ -59,8 +52,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, return AVERROR_INVALIDDATA; } - pic->reference = 0; - if ((ret = ff_get_buffer(avctx, pic)) < 0) { + if ((ret = ff_get_buffer(avctx, pic, 0)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } @@ -98,27 +90,15 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, } *got_frame = 1; - *(AVFrame*)data = *pic; return avpkt->size; } -static av_cold int decode_close(AVCodecContext *avctx) -{ - AVFrame *pic = avctx->coded_frame; - if (pic->data[0]) - avctx->release_buffer(avctx, pic); - av_freep(&avctx->coded_frame); - - return 0; -} - AVCodec ff_frwu_decoder = { .name = "frwu", .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_FRWU, .init = decode_init, - .close = decode_close, .decode = decode_frame, .capabilities = CODEC_CAP_DR1, .long_name = NULL_IF_CONFIG_SMALL("Forward Uncompressed"), diff --git a/libavcodec/g722dec.c b/libavcodec/g722dec.c index c100a90d34..100dab2f9b 100644 --- a/libavcodec/g722dec.c +++ b/libavcodec/g722dec.c @@ -94,7 +94,7 @@ static int g722_decode_frame(AVCodecContext *avctx, void *data, /* get output buffer */ frame->nb_samples = avpkt->size * 2; - if ((ret = ff_get_buffer(avctx, frame)) < 0) { + if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } diff --git a/libavcodec/g723_1.c b/libavcodec/g723_1.c index 377a718ffb..64b4e1fd4c 100644 --- a/libavcodec/g723_1.c +++ b/libavcodec/g723_1.c @@ -1218,7 +1218,7 @@ static int g723_1_decode_frame(AVCodecContext *avctx, void *data, } frame->nb_samples = FRAME_LEN; - if ((ret = ff_get_buffer(avctx, frame)) < 0) { + if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } diff --git a/libavcodec/g726.c b/libavcodec/g726.c index d6ae9b2679..e1448a1487 100644 --- a/libavcodec/g726.c +++ b/libavcodec/g726.c @@ -451,7 +451,7 @@ static int g726_decode_frame(AVCodecContext *avctx, void *data, /* get output buffer */ frame->nb_samples = out_samples; - if ((ret = ff_get_buffer(avctx, frame)) < 0) { + if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } diff --git a/libavcodec/gifdec.c b/libavcodec/gifdec.c index 2a962e5de0..9b74d342c8 100644 --- a/libavcodec/gifdec.c +++ b/libavcodec/gifdec.c @@ -34,7 +34,6 @@ #define GCE_DISPOSAL_RESTORE 3 typedef struct GifState { - AVFrame picture; int screen_width; int screen_height; int bits_per_pixel; @@ -63,7 +62,7 @@ typedef struct GifState { static const uint8_t gif87a_sig[6] = "GIF87a"; static const uint8_t gif89a_sig[6] = "GIF89a"; -static int gif_read_image(GifState *s) +static int gif_read_image(GifState *s, AVFrame *frame) { int left, top, width, height, bits_per_pixel, code_size, flags; int is_interleaved, has_local_palette, y, pass, y1, linesize, n, i; @@ -112,8 +111,8 @@ static int gif_read_image(GifState *s) s->bytestream_end - s->bytestream, FF_LZW_GIF); /* read all the image */ - linesize = s->picture.linesize[0]; - ptr1 = s->picture.data[0] + top * linesize + left; + linesize = frame->linesize[0]; + ptr1 = frame->data[0] + top * linesize + left; ptr = ptr1; pass = 0; y1 = 0; @@ -245,7 +244,7 @@ static int gif_read_header1(GifState *s) return 0; } -static int gif_parse_next_image(GifState *s) +static int gif_parse_next_image(GifState *s, AVFrame *frame) { while (s->bytestream < s->bytestream_end) { int code = bytestream_get_byte(&s->bytestream); @@ -255,7 +254,7 @@ static int gif_parse_next_image(GifState *s) switch (code) { case ',': - return gif_read_image(s); + return gif_read_image(s, frame); case '!': if ((ret = gif_read_extension(s)) < 0) return ret; @@ -276,9 +275,6 @@ static av_cold int gif_decode_init(AVCodecContext *avctx) s->avctx = avctx; - avcodec_get_frame_defaults(&s->picture); - avctx->coded_frame= &s->picture; - s->picture.data[0] = NULL; ff_lzw_decode_open(&s->lzw); return 0; } @@ -302,18 +298,15 @@ static int gif_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, return ret; avcodec_set_dimensions(avctx, s->screen_width, s->screen_height); - if (s->picture.data[0]) - avctx->release_buffer(avctx, &s->picture); - if ((ret = ff_get_buffer(avctx, &s->picture)) < 0) { + if ((ret = ff_get_buffer(avctx, picture, 0)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } - s->image_palette = (uint32_t *)s->picture.data[1]; - ret = gif_parse_next_image(s); + s->image_palette = (uint32_t *)picture->data[1]; + ret = gif_parse_next_image(s, picture); if (ret < 0) return ret; - *picture = s->picture; *got_frame = 1; return s->bytestream - buf; } @@ -323,8 +316,6 @@ static av_cold int gif_decode_close(AVCodecContext *avctx) GifState *s = avctx->priv_data; ff_lzw_decode_close(&s->lzw); - if(s->picture.data[0]) - avctx->release_buffer(avctx, &s->picture); return 0; } diff --git a/libavcodec/gsmdec.c b/libavcodec/gsmdec.c index e452be3fe0..d67f0b49c0 100644 --- a/libavcodec/gsmdec.c +++ b/libavcodec/gsmdec.c @@ -69,7 +69,7 @@ static int gsm_decode_frame(AVCodecContext *avctx, void *data, /* get output buffer */ frame->nb_samples = avctx->frame_size; - if ((res = ff_get_buffer(avctx, frame)) < 0) { + if ((res = ff_get_buffer(avctx, frame, 0)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return res; } diff --git a/libavcodec/h261dec.c b/libavcodec/h261dec.c index 35d5002252..d8ce66d24c 100644 --- a/libavcodec/h261dec.c +++ b/libavcodec/h261dec.c @@ -214,7 +214,7 @@ static int h261_decode_mb_skipped(H261Context *h, int mba1, int mba2 ) s->mv_dir = MV_DIR_FORWARD; s->mv_type = MV_TYPE_16X16; - s->current_picture.f.mb_type[xy] = MB_TYPE_SKIP | MB_TYPE_16x16 | MB_TYPE_L0; + s->current_picture.mb_type[xy] = MB_TYPE_SKIP | MB_TYPE_16x16 | MB_TYPE_L0; s->mv[0][0][0] = 0; s->mv[0][0][1] = 0; s->mb_skipped = 1; @@ -322,14 +322,14 @@ static int h261_decode_mb(H261Context *h){ } if(s->mb_intra){ - s->current_picture.f.mb_type[xy] = MB_TYPE_INTRA; + s->current_picture.mb_type[xy] = MB_TYPE_INTRA; goto intra; } //set motion vectors s->mv_dir = MV_DIR_FORWARD; s->mv_type = MV_TYPE_16X16; - s->current_picture.f.mb_type[xy] = MB_TYPE_16x16 | MB_TYPE_L0; + s->current_picture.mb_type[xy] = MB_TYPE_16x16 | MB_TYPE_L0; s->mv[0][0][0] = h->current_mv_x * 2;//gets divided by 2 in motion compensation s->mv[0][0][1] = h->current_mv_y * 2; @@ -624,8 +624,9 @@ retry: assert(s->current_picture.f.pict_type == s->current_picture_ptr->f.pict_type); assert(s->current_picture.f.pict_type == s->pict_type); - *pict = s->current_picture_ptr->f; - ff_print_debug_info(s, pict); + if ((ret = av_frame_ref(pict, &s->current_picture_ptr->f)) < 0) + return ret; + ff_print_debug_info(s, s->current_picture_ptr); *got_frame = 1; diff --git a/libavcodec/h263.c b/libavcodec/h263.c index 5ff47de76d..c097033951 100644 --- a/libavcodec/h263.c +++ b/libavcodec/h263.c @@ -51,7 +51,7 @@ void ff_h263_update_motion_val(MpegEncContext * s){ const int wrap = s->b8_stride; const int xy = s->block_index[0]; - s->current_picture.f.mbskip_table[mb_xy] = s->mb_skipped; + s->current_picture.mbskip_table[mb_xy] = s->mb_skipped; if(s->mv_type != MV_TYPE_8X8){ int motion_x, motion_y; @@ -70,30 +70,30 @@ void ff_h263_update_motion_val(MpegEncContext * s){ s->p_field_mv_table[i][0][mb_xy][0]= s->mv[0][i][0]; s->p_field_mv_table[i][0][mb_xy][1]= s->mv[0][i][1]; } - s->current_picture.f.ref_index[0][4*mb_xy ] = - s->current_picture.f.ref_index[0][4*mb_xy + 1] = s->field_select[0][0]; - s->current_picture.f.ref_index[0][4*mb_xy + 2] = - s->current_picture.f.ref_index[0][4*mb_xy + 3] = s->field_select[0][1]; + s->current_picture.ref_index[0][4*mb_xy ] = + s->current_picture.ref_index[0][4*mb_xy + 1] = s->field_select[0][0]; + s->current_picture.ref_index[0][4*mb_xy + 2] = + s->current_picture.ref_index[0][4*mb_xy + 3] = s->field_select[0][1]; } /* no update if 8X8 because it has been done during parsing */ - s->current_picture.f.motion_val[0][xy][0] = motion_x; - s->current_picture.f.motion_val[0][xy][1] = motion_y; - s->current_picture.f.motion_val[0][xy + 1][0] = motion_x; - s->current_picture.f.motion_val[0][xy + 1][1] = motion_y; - s->current_picture.f.motion_val[0][xy + wrap][0] = motion_x; - s->current_picture.f.motion_val[0][xy + wrap][1] = motion_y; - s->current_picture.f.motion_val[0][xy + 1 + wrap][0] = motion_x; - s->current_picture.f.motion_val[0][xy + 1 + wrap][1] = motion_y; + s->current_picture.motion_val[0][xy][0] = motion_x; + s->current_picture.motion_val[0][xy][1] = motion_y; + s->current_picture.motion_val[0][xy + 1][0] = motion_x; + s->current_picture.motion_val[0][xy + 1][1] = motion_y; + s->current_picture.motion_val[0][xy + wrap][0] = motion_x; + s->current_picture.motion_val[0][xy + wrap][1] = motion_y; + s->current_picture.motion_val[0][xy + 1 + wrap][0] = motion_x; + s->current_picture.motion_val[0][xy + 1 + wrap][1] = motion_y; } if(s->encoding){ //FIXME encoding MUST be cleaned up if (s->mv_type == MV_TYPE_8X8) - s->current_picture.f.mb_type[mb_xy] = MB_TYPE_L0 | MB_TYPE_8x8; + s->current_picture.mb_type[mb_xy] = MB_TYPE_L0 | MB_TYPE_8x8; else if(s->mb_intra) - s->current_picture.f.mb_type[mb_xy] = MB_TYPE_INTRA; + s->current_picture.mb_type[mb_xy] = MB_TYPE_INTRA; else - s->current_picture.f.mb_type[mb_xy] = MB_TYPE_L0 | MB_TYPE_16x16; + s->current_picture.mb_type[mb_xy] = MB_TYPE_L0 | MB_TYPE_16x16; } } @@ -153,7 +153,7 @@ void ff_h263_loop_filter(MpegEncContext * s){ Diag Top Left Center */ - if (!IS_SKIP(s->current_picture.f.mb_type[xy])) { + if (!IS_SKIP(s->current_picture.mb_type[xy])) { qp_c= s->qscale; s->dsp.h263_v_loop_filter(dest_y+8*linesize , linesize, qp_c); s->dsp.h263_v_loop_filter(dest_y+8*linesize+8, linesize, qp_c); @@ -163,10 +163,10 @@ void ff_h263_loop_filter(MpegEncContext * s){ if(s->mb_y){ int qp_dt, qp_tt, qp_tc; - if (IS_SKIP(s->current_picture.f.mb_type[xy - s->mb_stride])) + if (IS_SKIP(s->current_picture.mb_type[xy - s->mb_stride])) qp_tt=0; else - qp_tt = s->current_picture.f.qscale_table[xy - s->mb_stride]; + qp_tt = s->current_picture.qscale_table[xy - s->mb_stride]; if(qp_c) qp_tc= qp_c; @@ -186,10 +186,10 @@ void ff_h263_loop_filter(MpegEncContext * s){ s->dsp.h263_h_loop_filter(dest_y-8*linesize+8 , linesize, qp_tt); if(s->mb_x){ - if (qp_tt || IS_SKIP(s->current_picture.f.mb_type[xy - 1 - s->mb_stride])) + if (qp_tt || IS_SKIP(s->current_picture.mb_type[xy - 1 - s->mb_stride])) qp_dt= qp_tt; else - qp_dt = s->current_picture.f.qscale_table[xy - 1 - s->mb_stride]; + qp_dt = s->current_picture.qscale_table[xy - 1 - s->mb_stride]; if(qp_dt){ const int chroma_qp= s->chroma_qscale_table[qp_dt]; @@ -208,10 +208,10 @@ void ff_h263_loop_filter(MpegEncContext * s){ if(s->mb_x){ int qp_lc; - if (qp_c || IS_SKIP(s->current_picture.f.mb_type[xy - 1])) + if (qp_c || IS_SKIP(s->current_picture.mb_type[xy - 1])) qp_lc= qp_c; else - qp_lc = s->current_picture.f.qscale_table[xy - 1]; + qp_lc = s->current_picture.qscale_table[xy - 1]; if(qp_lc){ s->dsp.h263_h_loop_filter(dest_y, linesize, qp_lc); @@ -320,7 +320,7 @@ int16_t *ff_h263_pred_motion(MpegEncContext * s, int block, int dir, static const int off[4]= {2, 1, 1, -1}; wrap = s->b8_stride; - mot_val = s->current_picture.f.motion_val[dir] + s->block_index[block]; + mot_val = s->current_picture.motion_val[dir] + s->block_index[block]; A = mot_val[ - 1]; /* special case for first (slice) line */ diff --git a/libavcodec/h263dec.c b/libavcodec/h263dec.c index f5e1474789..28fb2dbbd5 100644 --- a/libavcodec/h263dec.c +++ b/libavcodec/h263dec.c @@ -359,7 +359,8 @@ uint64_t time= rdtsc(); if (buf_size == 0) { /* special case for last picture */ if (s->low_delay==0 && s->next_picture_ptr) { - *pict = s->next_picture_ptr->f; + if ((ret = av_frame_ref(pict, &s->next_picture_ptr->f)) < 0) + return ret; s->next_picture_ptr= NULL; *got_frame = 1; @@ -722,14 +723,17 @@ intrax8_decoded: assert(s->current_picture.f.pict_type == s->current_picture_ptr->f.pict_type); assert(s->current_picture.f.pict_type == s->pict_type); if (s->pict_type == AV_PICTURE_TYPE_B || s->low_delay) { - *pict = s->current_picture_ptr->f; + if ((ret = av_frame_ref(pict, &s->current_picture_ptr->f)) < 0) + return ret; + ff_print_debug_info(s, s->current_picture_ptr); } else if (s->last_picture_ptr != NULL) { - *pict = s->last_picture_ptr->f; + if ((ret = av_frame_ref(pict, &s->last_picture_ptr->f)) < 0) + return ret; + ff_print_debug_info(s, s->last_picture_ptr); } if(s->last_picture_ptr || s->low_delay){ *got_frame = 1; - ff_print_debug_info(s, pict); } #ifdef PRINT_FRAME_TIME diff --git a/libavcodec/h264.c b/libavcodec/h264.c index 0af5cea0d1..498f611a97 100644 --- a/libavcodec/h264.c +++ b/libavcodec/h264.c @@ -113,7 +113,7 @@ static void h264_er_decode_mb(void *opaque, int ref, int mv_dir, int mv_type, * practice then correct remapping should be added. */ if (ref >= h->ref_count[0]) ref = 0; - fill_rectangle(&h->cur_pic.f.ref_index[0][4 * h->mb_xy], + fill_rectangle(&h->cur_pic.ref_index[0][4 * h->mb_xy], 2, 2, 2, ref, 1); fill_rectangle(&h->ref_cache[0][scan8[0]], 4, 4, 8, ref, 1); fill_rectangle(h->mv_cache[0][scan8[0]], 4, 4, 8, @@ -166,28 +166,25 @@ void ff_h264_draw_horiz_band(H264Context *h, int y, int height) } } -static void free_frame_buffer(H264Context *h, Picture *pic) -{ - ff_thread_release_buffer(h->avctx, &pic->f); - av_freep(&pic->f.hwaccel_picture_private); -} - -static void free_picture(H264Context *h, Picture *pic) +static void unref_picture(H264Context *h, Picture *pic) { + int off = offsetof(Picture, tf) + sizeof(pic->tf); int i; - if (pic->f.data[0]) - free_frame_buffer(h, pic); + if (!pic->f.data[0]) + return; - av_freep(&pic->qscale_table_base); - pic->f.qscale_table = NULL; - av_freep(&pic->mb_type_base); - pic->f.mb_type = NULL; + ff_thread_release_buffer(h->avctx, &pic->tf); + av_buffer_unref(&pic->hwaccel_priv_buf); + + av_buffer_unref(&pic->qscale_table_buf); + av_buffer_unref(&pic->mb_type_buf); for (i = 0; i < 2; i++) { - av_freep(&pic->motion_val_base[i]); - av_freep(&pic->f.ref_index[i]); - pic->f.motion_val[i] = NULL; + av_buffer_unref(&pic->motion_val_buf[i]); + av_buffer_unref(&pic->ref_index_buf[i]); } + + memset((uint8_t*)pic + off, 0, sizeof(*pic) - off); } static void release_unused_pictures(H264Context *h, int remove_current) @@ -195,15 +192,74 @@ static void release_unused_pictures(H264Context *h, int remove_current) int i; /* release non reference frames */ - for (i = 0; i < h->picture_count; i++) { - if (h->DPB[i].f.data[0] && !h->DPB[i].f.reference && - (!h->DPB[i].owner2 || h->DPB[i].owner2 == h) && + for (i = 0; i < MAX_PICTURE_COUNT; i++) { + if (h->DPB[i].f.data[0] && !h->DPB[i].reference && (remove_current || &h->DPB[i] != h->cur_pic_ptr)) { - free_frame_buffer(h, &h->DPB[i]); + unref_picture(h, &h->DPB[i]); } } } +static int ref_picture(H264Context *h, Picture *dst, Picture *src) +{ + int ret, i; + + av_assert0(!dst->f.buf[0]); + av_assert0(src->f.buf[0]); + + src->tf.f = &src->f; + dst->tf.f = &dst->f; + ret = ff_thread_ref_frame(&dst->tf, &src->tf); + if (ret < 0) + goto fail; + + + dst->qscale_table_buf = av_buffer_ref(src->qscale_table_buf); + dst->mb_type_buf = av_buffer_ref(src->mb_type_buf); + if (!dst->qscale_table_buf || !dst->mb_type_buf) + goto fail; + dst->qscale_table = src->qscale_table; + dst->mb_type = src->mb_type; + + for (i = 0; i < 2; i ++) { + dst->motion_val_buf[i] = av_buffer_ref(src->motion_val_buf[i]); + dst->ref_index_buf[i] = av_buffer_ref(src->ref_index_buf[i]); + if (!dst->motion_val_buf[i] || !dst->ref_index_buf[i]) + goto fail; + dst->motion_val[i] = src->motion_val[i]; + dst->ref_index[i] = src->ref_index[i]; + } + + if (src->hwaccel_picture_private) { + dst->hwaccel_priv_buf = av_buffer_ref(src->hwaccel_priv_buf); + if (!dst->hwaccel_priv_buf) + goto fail; + dst->hwaccel_picture_private = dst->hwaccel_priv_buf->data; + } + + for (i = 0; i < 2; i++) + dst->field_poc[i] = src->field_poc[i]; + + memcpy(dst->ref_poc, src->ref_poc, sizeof(src->ref_poc)); + memcpy(dst->ref_count, src->ref_count, sizeof(src->ref_count)); + + dst->poc = src->poc; + dst->frame_num = src->frame_num; + dst->mmco_reset = src->mmco_reset; + dst->pic_id = src->pic_id; + dst->long_ref = src->long_ref; + dst->mbaff = src->mbaff; + dst->field_picture = src->field_picture; + dst->needs_realloc = src->needs_realloc; + dst->reference = src->reference; + + return 0; +fail: + unref_picture(h, dst); + return ret; +} + + static int alloc_scratch_buffers(H264Context *h, int linesize) { int alloc_size = FFALIGN(FFABS(linesize) + 32, 32); @@ -229,60 +285,86 @@ static int alloc_scratch_buffers(H264Context *h, int linesize) return 0; } -static int alloc_picture(H264Context *h, Picture *pic) +static int init_table_pools(H264Context *h) { const int big_mb_num = h->mb_stride * (h->mb_height + 1) + 1; const int mb_array_size = h->mb_stride * h->mb_height; const int b4_stride = h->mb_width * 4 + 1; const int b4_array_size = b4_stride * h->mb_height * 4; + + h->qscale_table_pool = av_buffer_pool_init(big_mb_num + h->mb_stride, + av_buffer_allocz); + h->mb_type_pool = av_buffer_pool_init((big_mb_num + h->mb_stride) * + sizeof(uint32_t), av_buffer_allocz); + h->motion_val_pool = av_buffer_pool_init(2 * (b4_array_size + 4) * + sizeof(int16_t), av_buffer_allocz); + h->ref_index_pool = av_buffer_pool_init(4 * mb_array_size, av_buffer_allocz); + + if (!h->qscale_table_pool || !h->mb_type_pool || !h->motion_val_pool || + !h->ref_index_pool) { + av_buffer_pool_uninit(&h->qscale_table_pool); + av_buffer_pool_uninit(&h->mb_type_pool); + av_buffer_pool_uninit(&h->motion_val_pool); + av_buffer_pool_uninit(&h->ref_index_pool); + return AVERROR(ENOMEM); + } + + return 0; +} + +static int alloc_picture(H264Context *h, Picture *pic) +{ int i, ret = 0; av_assert0(!pic->f.data[0]); if (h->avctx->hwaccel) { const AVHWAccel *hwaccel = h->avctx->hwaccel; - av_assert0(!pic->f.hwaccel_picture_private); + av_assert0(!pic->hwaccel_picture_private); if (hwaccel->priv_data_size) { - pic->f.hwaccel_picture_private = av_mallocz(hwaccel->priv_data_size); - if (!pic->f.hwaccel_picture_private) + pic->hwaccel_priv_buf = av_buffer_allocz(hwaccel->priv_data_size); + if (!pic->hwaccel_priv_buf) return AVERROR(ENOMEM); + pic->hwaccel_picture_private = pic->hwaccel_priv_buf->data; } } - ret = ff_thread_get_buffer(h->avctx, &pic->f); + pic->tf.f = &pic->f; + ret = ff_thread_get_buffer(h->avctx, &pic->tf, pic->reference ? + AV_GET_BUFFER_FLAG_REF : 0); if (ret < 0) goto fail; h->linesize = pic->f.linesize[0]; h->uvlinesize = pic->f.linesize[1]; - if (pic->f.qscale_table == NULL) { - FF_ALLOCZ_OR_GOTO(h->avctx, pic->qscale_table_base, - (big_mb_num + h->mb_stride) * sizeof(uint8_t), - fail) - FF_ALLOCZ_OR_GOTO(h->avctx, pic->mb_type_base, - (big_mb_num + h->mb_stride) * sizeof(uint32_t), - fail) - pic->f.mb_type = pic->mb_type_base + 2 * h->mb_stride + 1; - pic->f.qscale_table = pic->qscale_table_base + 2 * h->mb_stride + 1; - - for (i = 0; i < 2; i++) { - FF_ALLOCZ_OR_GOTO(h->avctx, pic->motion_val_base[i], - 2 * (b4_array_size + 4) * sizeof(int16_t), - fail) - pic->f.motion_val[i] = pic->motion_val_base[i] + 4; - FF_ALLOCZ_OR_GOTO(h->avctx, pic->f.ref_index[i], - 4 * mb_array_size * sizeof(uint8_t), fail) - } - pic->f.motion_subsample_log2 = 2; - - pic->f.qstride = h->mb_stride; + if (!h->qscale_table_pool) { + ret = init_table_pools(h); + if (ret < 0) + goto fail; } - pic->owner2 = h; + pic->qscale_table_buf = av_buffer_pool_get(h->qscale_table_pool); + pic->mb_type_buf = av_buffer_pool_get(h->mb_type_pool); + if (!pic->qscale_table_buf || !pic->mb_type_buf) + goto fail; + + pic->mb_type = (uint32_t*)pic->mb_type_buf->data + 2 * h->mb_stride + 1; + pic->qscale_table = pic->qscale_table_buf->data + 2 * h->mb_stride + 1; + + for (i = 0; i < 2; i++) { + pic->motion_val_buf[i] = av_buffer_pool_get(h->motion_val_pool); + pic->ref_index_buf[i] = av_buffer_pool_get(h->ref_index_pool); + if (!pic->motion_val_buf[i] || !pic->ref_index_buf[i]) + goto fail; + + pic->motion_val[i] = (int16_t (*)[2])pic->motion_val_buf[i]->data + 4; + pic->ref_index[i] = pic->ref_index_buf[i]->data; + } + pic->f.motion_subsample_log2 = 2; return 0; fail: - free_frame_buffer(h, pic); + unref_picture(h, pic); return (ret < 0) ? ret : AVERROR(ENOMEM); } @@ -290,9 +372,8 @@ static inline int pic_is_unused(H264Context *h, Picture *pic) { if (pic->f.data[0] == NULL) return 1; - if (pic->needs_realloc && !(pic->f.reference & DELAYED_PIC_REF)) - if (!pic->owner2 || pic->owner2 == h) - return 1; + if (pic->needs_realloc && !(pic->reference & DELAYED_PIC_REF)) + return 1; return 0; } @@ -300,17 +381,16 @@ static int find_unused_picture(H264Context *h) { int i; - for (i = h->picture_range_start; i < h->picture_range_end; i++) { + for (i = 0; i < MAX_PICTURE_COUNT; i++) { if (pic_is_unused(h, &h->DPB[i])) break; } - if (i == h->picture_range_end) + if (i == MAX_PICTURE_COUNT) return AVERROR_INVALIDDATA; if (h->DPB[i].needs_realloc) { h->DPB[i].needs_realloc = 0; - free_picture(h, &h->DPB[i]); - avcodec_get_frame_defaults(&h->DPB[i].f); + unref_picture(h, &h->DPB[i]); } return i; @@ -561,8 +641,8 @@ static inline void get_lowest_part_y(H264Context *h, int refs[2][48], int n, // Error resilience puts the current picture in the ref list. // Don't try to wait on these as it will cause a deadlock. // Fields can wait on each other, though. - if (ref->f.thread_opaque != h->cur_pic.f.thread_opaque || - (ref->f.reference & 3) != h->picture_structure) { + if (ref->tf.progress->data != h->cur_pic.tf.progress->data || + (ref->reference & 3) != h->picture_structure) { my = get_lowest_part_list_y(h, ref, n, height, y_offset, 0); if (refs[0][ref_n] < 0) nrefs[0] += 1; @@ -574,8 +654,8 @@ static inline void get_lowest_part_y(H264Context *h, int refs[2][48], int n, int ref_n = h->ref_cache[1][scan8[n]]; Picture *ref = &h->ref_list[1][ref_n]; - if (ref->f.thread_opaque != h->cur_pic.f.thread_opaque || - (ref->f.reference & 3) != h->picture_structure) { + if (ref->tf.progress->data != h->cur_pic.tf.progress->data || + (ref->reference & 3) != h->picture_structure) { my = get_lowest_part_list_y(h, ref, n, height, y_offset, 1); if (refs[1][ref_n] < 0) nrefs[1] += 1; @@ -592,7 +672,7 @@ static inline void get_lowest_part_y(H264Context *h, int refs[2][48], int n, static void await_references(H264Context *h) { const int mb_xy = h->mb_xy; - const int mb_type = h->cur_pic.f.mb_type[mb_xy]; + const int mb_type = h->cur_pic.mb_type[mb_xy]; int refs[2][48]; int nrefs[2] = { 0 }; int ref, list; @@ -664,7 +744,7 @@ static void await_references(H264Context *h) int row = refs[list][ref]; if (row >= 0) { Picture *ref_pic = &h->ref_list[list][ref]; - int ref_field = ref_pic->f.reference - 1; + int ref_field = ref_pic->reference - 1; int ref_field_picture = ref_pic->field_picture; int pic_height = 16 * h->mb_height >> ref_field_picture; @@ -672,24 +752,24 @@ static void await_references(H264Context *h) nrefs[list]--; if (!FIELD_PICTURE && ref_field_picture) { // frame referencing two fields - ff_thread_await_progress(&ref_pic->f, + ff_thread_await_progress(&ref_pic->tf, FFMIN((row >> 1) - !(row & 1), pic_height - 1), 1); - ff_thread_await_progress(&ref_pic->f, + ff_thread_await_progress(&ref_pic->tf, FFMIN((row >> 1), pic_height - 1), 0); } else if (FIELD_PICTURE && !ref_field_picture) { // field referencing one field of a frame - ff_thread_await_progress(&ref_pic->f, + ff_thread_await_progress(&ref_pic->tf, FFMIN(row * 2 + ref_field, pic_height - 1), 0); } else if (FIELD_PICTURE) { - ff_thread_await_progress(&ref_pic->f, + ff_thread_await_progress(&ref_pic->tf, FFMIN(row, pic_height - 1), ref_field); } else { - ff_thread_await_progress(&ref_pic->f, + ff_thread_await_progress(&ref_pic->tf, FFMIN(row, pic_height - 1), 0); } @@ -781,7 +861,7 @@ static av_always_inline void mc_dir_part(H264Context *h, Picture *pic, ysh = 3 - (chroma_idc == 2 /* yuv422 */); if (chroma_idc == 1 /* yuv420 */ && MB_FIELD) { // chroma offset when predicting from a field of opposite parity - my += 2 * ((h->mb_y & 1) - (pic->f.reference - 1)); + my += 2 * ((h->mb_y & 1) - (pic->reference - 1)); emu |= (my >> 3) < 0 || (my >> 3) + 8 >= (pic_height >> 1); } @@ -1009,13 +1089,17 @@ static void free_tables(H264Context *h, int free_rbsp) av_freep(&h->mb2b_xy); av_freep(&h->mb2br_xy); - if (free_rbsp) { - for (i = 0; i < h->picture_count && !h->avctx->internal->is_copy; i++) - free_picture(h, &h->DPB[i]); + av_buffer_pool_uninit(&h->qscale_table_pool); + av_buffer_pool_uninit(&h->mb_type_pool); + av_buffer_pool_uninit(&h->motion_val_pool); + av_buffer_pool_uninit(&h->ref_index_pool); + + if (free_rbsp && h->DPB) { + for (i = 0; i < MAX_PICTURE_COUNT; i++) + unref_picture(h, &h->DPB[i]); av_freep(&h->DPB); - h->picture_count = 0; } else if (h->DPB) { - for (i = 0; i < h->picture_count; i++) + for (i = 0; i < MAX_PICTURE_COUNT; i++) h->DPB[i].needs_realloc = 1; } @@ -1164,11 +1248,10 @@ int ff_h264_alloc_tables(H264Context *h) init_dequant_tables(h); if (!h->DPB) { - h->picture_count = MAX_PICTURE_COUNT * FFMAX(1, h->avctx->thread_count); - h->DPB = av_mallocz_array(h->picture_count, sizeof(*h->DPB)); + h->DPB = av_mallocz_array(MAX_PICTURE_COUNT, sizeof(*h->DPB)); if (!h->DPB) return AVERROR(ENOMEM); - for (i = 0; i < h->picture_count; i++) + for (i = 0; i < MAX_PICTURE_COUNT; i++) avcodec_get_frame_defaults(&h->DPB[i].f); avcodec_get_frame_defaults(&h->cur_pic.f); } @@ -1367,8 +1450,6 @@ av_cold int ff_h264_decode_init(AVCodecContext *avctx) common_init(h); h->picture_structure = PICT_FRAME; - h->picture_range_start = 0; - h->picture_range_end = MAX_PICTURE_COUNT; h->slice_context_count = 1; h->workaround_bugs = avctx->workaround_bugs; h->flags = avctx->flags; @@ -1408,6 +1489,8 @@ av_cold int ff_h264_decode_init(AVCodecContext *avctx) h->low_delay = 0; } + avctx->internal->allocate_progress = 1; + return 0; } @@ -1415,7 +1498,7 @@ av_cold int ff_h264_decode_init(AVCodecContext *avctx) #undef REBASE_PICTURE #define REBASE_PICTURE(pic, new_ctx, old_ctx) \ ((pic && pic >= old_ctx->DPB && \ - pic < old_ctx->DPB + old_ctx->picture_count) ? \ + pic < old_ctx->DPB + MAX_PICTURE_COUNT) ? \ &new_ctx->DPB[pic - old_ctx->DPB] : NULL) static void copy_picture_range(Picture **to, Picture **from, int count, @@ -1427,7 +1510,7 @@ static void copy_picture_range(Picture **to, Picture **from, int count, for (i = 0; i < count; i++) { assert((IN_RANGE(from[i], old_base, sizeof(*old_base)) || IN_RANGE(from[i], old_base->DPB, - sizeof(Picture) * old_base->picture_count) || + sizeof(Picture) * MAX_PICTURE_COUNT) || !from[i])); to[i] = REBASE_PICTURE(from[i], new_base, old_base); } @@ -1476,7 +1559,7 @@ static int decode_update_thread_context(AVCodecContext *dst, H264Context *h = dst->priv_data, *h1 = src->priv_data; int inited = h->context_initialized, err = 0; int context_reinitialized = 0; - int i; + int i, ret; if (dst == src || !h1->context_initialized) return 0; @@ -1529,12 +1612,16 @@ static int decode_update_thread_context(AVCodecContext *dst, memset(&h->me, 0, sizeof(h->me)); h->context_initialized = 0; - h->picture_range_start += MAX_PICTURE_COUNT; - h->picture_range_end += MAX_PICTURE_COUNT; + memset(&h->cur_pic, 0, sizeof(h->cur_pic)); + avcodec_get_frame_defaults(&h->cur_pic.f); + h->cur_pic.tf.f = &h->cur_pic.f; h->avctx = dst; h->DPB = NULL; - h->cur_pic.f.extended_data = h->cur_pic.f.data; + h->qscale_table_pool = NULL; + h->mb_type_pool = NULL; + h->ref_index_pool = NULL; + h->motion_val_pool = NULL; if (ff_h264_alloc_tables(h) < 0) { av_log(dst, AV_LOG_ERROR, "Could not allocate memory for h264\n"); @@ -1568,15 +1655,17 @@ static int decode_update_thread_context(AVCodecContext *dst, h->data_partitioning = h1->data_partitioning; h->low_delay = h1->low_delay; - memcpy(h->DPB, h1->DPB, h1->picture_count * sizeof(*h1->DPB)); - - // reset s->picture[].f.extended_data to s->picture[].f.data - for (i = 0; i < h->picture_count; i++) - h->DPB[i].f.extended_data = h->DPB[i].f.data; + for (i = 0; i < MAX_PICTURE_COUNT; i++) { + unref_picture(h, &h->DPB[i]); + if (h1->DPB[i].f.data[0] && + (ret = ref_picture(h, &h->DPB[i], &h1->DPB[i])) < 0) + return ret; + } h->cur_pic_ptr = REBASE_PICTURE(h1->cur_pic_ptr, h, h1); - h->cur_pic = h1->cur_pic; - h->cur_pic.f.extended_data = h->cur_pic.f.data; + unref_picture(h, &h->cur_pic); + if ((ret = ref_picture(h, &h->cur_pic, &h1->cur_pic)) < 0) + return ret; h->workaround_bugs = h1->workaround_bugs; h->low_delay = h1->low_delay; @@ -1660,7 +1749,7 @@ int ff_h264_frame_start(H264Context *h) } pic = &h->DPB[i]; - pic->f.reference = h->droppable ? 0 : h->picture_structure; + pic->reference = h->droppable ? 0 : h->picture_structure; pic->f.coded_picture_number = h->coded_picture_number++; pic->field_picture = h->picture_structure != PICT_FRAME; /* @@ -1675,8 +1764,9 @@ int ff_h264_frame_start(H264Context *h) return ret; h->cur_pic_ptr = pic; - h->cur_pic = *h->cur_pic_ptr; - h->cur_pic.f.extended_data = h->cur_pic.f.data; + unref_picture(h, &h->cur_pic); + if ((ret = ref_picture(h, &h->cur_pic, h->cur_pic_ptr)) < 0) + return ret; ff_er_frame_start(&h->er); @@ -1717,7 +1807,7 @@ int ff_h264_frame_start(H264Context *h) * get released even with set reference, besides SVQ3 and others do not * mark frames as reference later "naturally". */ if (h->avctx->codec_id != AV_CODEC_ID_SVQ3) - h->cur_pic_ptr->f.reference = 0; + h->cur_pic_ptr->reference = 0; h->cur_pic_ptr->field_poc[0] = h->cur_pic_ptr->field_poc[1] = INT_MAX; @@ -1743,7 +1833,6 @@ static void decode_postinit(H264Context *h, int setup_finished) int i, pics, out_of_order, out_idx; int invalid = 0, cnt = 0; - h->cur_pic_ptr->f.qscale_type = FF_QSCALE_TYPE_H264; h->cur_pic_ptr->f.pict_type = h->pict_type; if (h->next_output_pic) @@ -1847,8 +1936,8 @@ static void decode_postinit(H264Context *h, int setup_finished) assert(pics <= MAX_DELAYED_PIC_COUNT); h->delayed_pic[pics++] = cur; - if (cur->f.reference == 0) - cur->f.reference = DELAYED_PIC_REF; + if (cur->reference == 0) + cur->reference = DELAYED_PIC_REF; /* Frame reordering. This code takes pictures from coding order and sorts * them by their incremental POC value into display order. It supports POC @@ -1913,10 +2002,9 @@ static void decode_postinit(H264Context *h, int setup_finished) } if (pics > h->avctx->has_b_frames) { - out->f.reference &= ~DELAYED_PIC_REF; + out->reference &= ~DELAYED_PIC_REF; // for frame threading, the owner must be the second field's thread or // else the first thread can release the picture and reuse it unsafely - out->owner2 = h; for (i = out_idx; h->delayed_pic[i]; i++) h->delayed_pic[i] = h->delayed_pic[i + 1]; } @@ -2350,7 +2438,7 @@ static av_always_inline void hl_decode_mb_idct_luma(H264Context *h, int mb_type, void ff_h264_hl_decode_mb(H264Context *h) { const int mb_xy = h->mb_xy; - const int mb_type = h->cur_pic.f.mb_type[mb_xy]; + const int mb_type = h->cur_pic.mb_type[mb_xy]; int is_complex = CONFIG_SMALL || h->is_complex || IS_INTRA_PCM(mb_type) || h->qscale == 0; if (CHROMA444) { @@ -2516,7 +2604,7 @@ static void flush_change(H264Context *h) h->prev_interlaced_frame = 1; idr(h); if (h->cur_pic_ptr) - h->cur_pic_ptr->f.reference = 0; + h->cur_pic_ptr->reference = 0; h->first_field = 0; memset(h->ref_list[0], 0, sizeof(h->ref_list[0])); memset(h->ref_list[1], 0, sizeof(h->ref_list[1])); @@ -2533,17 +2621,16 @@ static void flush_dpb(AVCodecContext *avctx) for (i = 0; i < MAX_DELAYED_PIC_COUNT; i++) { if (h->delayed_pic[i]) - h->delayed_pic[i]->f.reference = 0; + h->delayed_pic[i]->reference = 0; h->delayed_pic[i] = NULL; } flush_change(h); - for (i = 0; i < h->picture_count; i++) { - if (h->DPB[i].f.data[0]) - free_frame_buffer(h, &h->DPB[i]); - } + for (i = 0; i < MAX_PICTURE_COUNT; i++) + unref_picture(h, &h->DPB[i]); h->cur_pic_ptr = NULL; + unref_picture(h, &h->cur_pic); h->mb_x = h->mb_y = 0; @@ -2676,7 +2763,7 @@ static int field_end(H264Context *h, int in_setup) h->mb_y = 0; if (!in_setup && !h->droppable) - ff_thread_report_progress(&h->cur_pic_ptr->f, INT_MAX, + ff_thread_report_progress(&h->cur_pic_ptr->tf, INT_MAX, h->picture_structure == PICT_BOTTOM_FIELD); if (CONFIG_H264_VDPAU_DECODER && @@ -3019,9 +3106,8 @@ static int decode_slice_header(H264Context *h, H264Context *h0) h0->current_slice = 0; if (!h0->first_field) { - if (h->cur_pic_ptr && !h->droppable && - h->cur_pic_ptr->owner2 == h) { - ff_thread_report_progress(&h->cur_pic_ptr->f, INT_MAX, + if (h->cur_pic_ptr && !h->droppable) { + ff_thread_report_progress(&h->cur_pic_ptr->tf, INT_MAX, h->picture_structure == PICT_BOTTOM_FIELD); } h->cur_pic_ptr = NULL; @@ -3240,20 +3326,14 @@ static int decode_slice_header(H264Context *h, H264Context *h0) if (h0->first_field) { assert(h0->cur_pic_ptr); assert(h0->cur_pic_ptr->f.data[0]); - assert(h0->cur_pic_ptr->f.reference != DELAYED_PIC_REF); - - /* Mark old field/frame as completed */ - if (!last_pic_droppable && h0->cur_pic_ptr->owner2 == h0) { - ff_thread_report_progress(&h0->cur_pic_ptr->f, INT_MAX, - last_pic_structure == PICT_BOTTOM_FIELD); - } + assert(h0->cur_pic_ptr->reference != DELAYED_PIC_REF); /* figure out if we have a complementary field pair */ if (!FIELD_PICTURE || h->picture_structure == last_pic_structure) { /* Previous field is unmatched. Don't display it, but let it * remain for reference if marked as such. */ if (!last_pic_droppable && last_pic_structure != PICT_FRAME) { - ff_thread_report_progress(&h0->cur_pic_ptr->f, INT_MAX, + ff_thread_report_progress(&h0->cur_pic_ptr->tf, INT_MAX, last_pic_structure == PICT_TOP_FIELD); } } else { @@ -3263,7 +3343,7 @@ static int decode_slice_header(H264Context *h, H264Context *h0) * pair. Throw away previous field except for reference * purposes. */ if (!last_pic_droppable && last_pic_structure != PICT_FRAME) { - ff_thread_report_progress(&h0->cur_pic_ptr->f, INT_MAX, + ff_thread_report_progress(&h0->cur_pic_ptr->tf, INT_MAX, last_pic_structure == PICT_TOP_FIELD); } } else { @@ -3286,14 +3366,6 @@ static int decode_slice_header(H264Context *h, H264Context *h0) h->droppable = last_pic_droppable; return AVERROR_PATCHWELCOME; } - - /* Take ownership of this buffer. Note that if another thread owned - * the first field of this buffer, we're not operating on that pointer, - * so the original thread is still responsible for reporting progress - * on that first field (or if that was us, we just did that above). - * By taking ownership, we assign responsibility to ourselves to - * report progress on the second field. */ - h0->cur_pic_ptr->owner2 = h0; } } } @@ -3308,8 +3380,8 @@ static int decode_slice_header(H264Context *h, H264Context *h0) h->prev_frame_num++; h->prev_frame_num %= 1 << h->sps.log2_max_frame_num; h->cur_pic_ptr->frame_num = h->prev_frame_num; - ff_thread_report_progress(&h->cur_pic_ptr->f, INT_MAX, 0); - ff_thread_report_progress(&h->cur_pic_ptr->f, INT_MAX, 1); + ff_thread_report_progress(&h->cur_pic_ptr->tf, INT_MAX, 0); + ff_thread_report_progress(&h->cur_pic_ptr->tf, INT_MAX, 1); if ((ret = ff_generate_sliding_window_mmcos(h, 1)) < 0 && h->avctx->err_recognition & AV_EF_EXPLODE) return ret; @@ -3339,7 +3411,7 @@ static int decode_slice_header(H264Context *h, H264Context *h0) if (h0->first_field) { assert(h0->cur_pic_ptr); assert(h0->cur_pic_ptr->f.data[0]); - assert(h0->cur_pic_ptr->f.reference != DELAYED_PIC_REF); + assert(h0->cur_pic_ptr->reference != DELAYED_PIC_REF); /* figure out if we have a complementary field pair */ if (!FIELD_PICTURE || h->picture_structure == last_pic_structure) { @@ -3606,16 +3678,16 @@ static int decode_slice_header(H264Context *h, H264Context *h0) int *ref2frm = h->ref2frm[h->slice_num & (MAX_SLICES - 1)][j]; for (i = 0; i < 16; i++) { id_list[i] = 60; - if (h->ref_list[j][i].f.data[0]) { + if (j < h->list_count && i < h->ref_count[j] && h->ref_list[j][i].f.buf[0]) { int k; - uint8_t *base = h->ref_list[j][i].f.base[0]; + AVBuffer *buf = h->ref_list[j][i].f.buf[0]->buffer; for (k = 0; k < h->short_ref_count; k++) - if (h->short_ref[k]->f.base[0] == base) { + if (h->short_ref[k]->f.buf[0]->buffer == buf) { id_list[i] = k; break; } for (k = 0; k < h->long_ref_count; k++) - if (h->long_ref[k] && h->long_ref[k]->f.base[0] == base) { + if (h->long_ref[k] && h->long_ref[k]->f.buf[0]->buffer == buf) { id_list[i] = h->short_ref_count + k; break; } @@ -3626,12 +3698,12 @@ static int decode_slice_header(H264Context *h, H264Context *h0) ref2frm[1] = -1; for (i = 0; i < 16; i++) ref2frm[i + 2] = 4 * id_list[i] + - (h->ref_list[j][i].f.reference & 3); + (h->ref_list[j][i].reference & 3); ref2frm[18 + 0] = ref2frm[18 + 1] = -1; for (i = 16; i < 48; i++) ref2frm[i + 4] = 4 * id_list[(i - 16) >> 1] + - (h->ref_list[j][i].f.reference & 3); + (h->ref_list[j][i].reference & 3); } if (h->avctx->debug & FF_DEBUG_PICT_INFO) { @@ -3691,11 +3763,11 @@ static av_always_inline void fill_filter_caches_inter(H264Context *h, const int b_xy = h->mb2b_xy[top_xy] + 3 * b_stride; const int b8_xy = 4 * top_xy + 2; int (*ref2frm)[64] = h->ref2frm[h->slice_table[top_xy] & (MAX_SLICES - 1)][0] + (MB_MBAFF ? 20 : 2); - AV_COPY128(mv_dst - 1 * 8, h->cur_pic.f.motion_val[list][b_xy + 0]); + AV_COPY128(mv_dst - 1 * 8, h->cur_pic.motion_val[list][b_xy + 0]); ref_cache[0 - 1 * 8] = - ref_cache[1 - 1 * 8] = ref2frm[list][h->cur_pic.f.ref_index[list][b8_xy + 0]]; + ref_cache[1 - 1 * 8] = ref2frm[list][h->cur_pic.ref_index[list][b8_xy + 0]]; ref_cache[2 - 1 * 8] = - ref_cache[3 - 1 * 8] = ref2frm[list][h->cur_pic.f.ref_index[list][b8_xy + 1]]; + ref_cache[3 - 1 * 8] = ref2frm[list][h->cur_pic.ref_index[list][b8_xy + 1]]; } else { AV_ZERO128(mv_dst - 1 * 8); AV_WN32A(&ref_cache[0 - 1 * 8], ((LIST_NOT_USED) & 0xFF) * 0x01010101u); @@ -3706,14 +3778,14 @@ static av_always_inline void fill_filter_caches_inter(H264Context *h, const int b_xy = h->mb2b_xy[left_xy[LTOP]] + 3; const int b8_xy = 4 * left_xy[LTOP] + 1; int (*ref2frm)[64] = h->ref2frm[h->slice_table[left_xy[LTOP]] & (MAX_SLICES - 1)][0] + (MB_MBAFF ? 20 : 2); - AV_COPY32(mv_dst - 1 + 0, h->cur_pic.f.motion_val[list][b_xy + b_stride * 0]); - AV_COPY32(mv_dst - 1 + 8, h->cur_pic.f.motion_val[list][b_xy + b_stride * 1]); - AV_COPY32(mv_dst - 1 + 16, h->cur_pic.f.motion_val[list][b_xy + b_stride * 2]); - AV_COPY32(mv_dst - 1 + 24, h->cur_pic.f.motion_val[list][b_xy + b_stride * 3]); + AV_COPY32(mv_dst - 1 + 0, h->cur_pic.motion_val[list][b_xy + b_stride * 0]); + AV_COPY32(mv_dst - 1 + 8, h->cur_pic.motion_val[list][b_xy + b_stride * 1]); + AV_COPY32(mv_dst - 1 + 16, h->cur_pic.motion_val[list][b_xy + b_stride * 2]); + AV_COPY32(mv_dst - 1 + 24, h->cur_pic.motion_val[list][b_xy + b_stride * 3]); ref_cache[-1 + 0] = - ref_cache[-1 + 8] = ref2frm[list][h->cur_pic.f.ref_index[list][b8_xy + 2 * 0]]; + ref_cache[-1 + 8] = ref2frm[list][h->cur_pic.ref_index[list][b8_xy + 2 * 0]]; ref_cache[-1 + 16] = - ref_cache[-1 + 24] = ref2frm[list][h->cur_pic.f.ref_index[list][b8_xy + 2 * 1]]; + ref_cache[-1 + 24] = ref2frm[list][h->cur_pic.ref_index[list][b8_xy + 2 * 1]]; } else { AV_ZERO32(mv_dst - 1 + 0); AV_ZERO32(mv_dst - 1 + 8); @@ -3737,7 +3809,7 @@ static av_always_inline void fill_filter_caches_inter(H264Context *h, } { - int8_t *ref = &h->cur_pic.f.ref_index[list][4 * mb_xy]; + int8_t *ref = &h->cur_pic.ref_index[list][4 * mb_xy]; int (*ref2frm)[64] = h->ref2frm[h->slice_num & (MAX_SLICES - 1)][0] + (MB_MBAFF ? 20 : 2); uint32_t ref01 = (pack16to32(ref2frm[list][ref[0]], ref2frm[list][ref[1]]) & 0x00FF00FF) * 0x0101; uint32_t ref23 = (pack16to32(ref2frm[list][ref[2]], ref2frm[list][ref[3]]) & 0x00FF00FF) * 0x0101; @@ -3748,7 +3820,7 @@ static av_always_inline void fill_filter_caches_inter(H264Context *h, } { - int16_t(*mv_src)[2] = &h->cur_pic.f.motion_val[list][4 * h->mb_x + 4 * h->mb_y * b_stride]; + int16_t(*mv_src)[2] = &h->cur_pic.motion_val[list][4 * h->mb_x + 4 * h->mb_y * b_stride]; AV_COPY128(mv_dst + 8 * 0, mv_src + 0 * b_stride); AV_COPY128(mv_dst + 8 * 1, mv_src + 1 * b_stride); AV_COPY128(mv_dst + 8 * 2, mv_src + 2 * b_stride); @@ -3775,7 +3847,7 @@ static int fill_filter_caches(H264Context *h, int mb_type) left_xy[LBOT] = left_xy[LTOP] = mb_xy - 1; if (FRAME_MBAFF) { - const int left_mb_field_flag = IS_INTERLACED(h->cur_pic.f.mb_type[mb_xy - 1]); + const int left_mb_field_flag = IS_INTERLACED(h->cur_pic.mb_type[mb_xy - 1]); const int curr_mb_field_flag = IS_INTERLACED(mb_type); if (h->mb_y & 1) { if (left_mb_field_flag != curr_mb_field_flag) @@ -3783,7 +3855,7 @@ static int fill_filter_caches(H264Context *h, int mb_type) } else { if (curr_mb_field_flag) top_xy += h->mb_stride & - (((h->cur_pic.f.mb_type[top_xy] >> 7) & 1) - 1); + (((h->cur_pic.mb_type[top_xy] >> 7) & 1) - 1); if (left_mb_field_flag != curr_mb_field_flag) left_xy[LBOT] += h->mb_stride; } @@ -3797,25 +3869,25 @@ static int fill_filter_caches(H264Context *h, int mb_type) * This is a conservative estimate: could also check beta_offset * and more accurate chroma_qp. */ int qp_thresh = h->qp_thresh; // FIXME strictly we should store qp_thresh for each mb of a slice - int qp = h->cur_pic.f.qscale_table[mb_xy]; + int qp = h->cur_pic.qscale_table[mb_xy]; if (qp <= qp_thresh && (left_xy[LTOP] < 0 || - ((qp + h->cur_pic.f.qscale_table[left_xy[LTOP]] + 1) >> 1) <= qp_thresh) && + ((qp + h->cur_pic.qscale_table[left_xy[LTOP]] + 1) >> 1) <= qp_thresh) && (top_xy < 0 || - ((qp + h->cur_pic.f.qscale_table[top_xy] + 1) >> 1) <= qp_thresh)) { + ((qp + h->cur_pic.qscale_table[top_xy] + 1) >> 1) <= qp_thresh)) { if (!FRAME_MBAFF) return 1; if ((left_xy[LTOP] < 0 || - ((qp + h->cur_pic.f.qscale_table[left_xy[LBOT]] + 1) >> 1) <= qp_thresh) && + ((qp + h->cur_pic.qscale_table[left_xy[LBOT]] + 1) >> 1) <= qp_thresh) && (top_xy < h->mb_stride || - ((qp + h->cur_pic.f.qscale_table[top_xy - h->mb_stride] + 1) >> 1) <= qp_thresh)) + ((qp + h->cur_pic.qscale_table[top_xy - h->mb_stride] + 1) >> 1) <= qp_thresh)) return 1; } } - top_type = h->cur_pic.f.mb_type[top_xy]; - left_type[LTOP] = h->cur_pic.f.mb_type[left_xy[LTOP]]; - left_type[LBOT] = h->cur_pic.f.mb_type[left_xy[LBOT]]; + top_type = h->cur_pic.mb_type[top_xy]; + left_type[LTOP] = h->cur_pic.mb_type[left_xy[LTOP]]; + left_type[LBOT] = h->cur_pic.mb_type[left_xy[LBOT]]; if (h->deblocking_filter == 2) { if (h->slice_table[top_xy] != h->slice_num) top_type = 0; @@ -3920,7 +3992,7 @@ static void loop_filter(H264Context *h, int start_x, int end_x) int mb_xy, mb_type; mb_xy = h->mb_xy = mb_x + mb_y * h->mb_stride; h->slice_num = h->slice_table[mb_xy]; - mb_type = h->cur_pic.f.mb_type[mb_xy]; + mb_type = h->cur_pic.mb_type[mb_xy]; h->list_count = h->list_counts[mb_xy]; if (FRAME_MBAFF) @@ -3955,8 +4027,8 @@ static void loop_filter(H264Context *h, int start_x, int end_x) uvlinesize, 0); if (fill_filter_caches(h, mb_type)) continue; - h->chroma_qp[0] = get_chroma_qp(h, 0, h->cur_pic.f.qscale_table[mb_xy]); - h->chroma_qp[1] = get_chroma_qp(h, 1, h->cur_pic.f.qscale_table[mb_xy]); + h->chroma_qp[0] = get_chroma_qp(h, 0, h->cur_pic.qscale_table[mb_xy]); + h->chroma_qp[1] = get_chroma_qp(h, 1, h->cur_pic.qscale_table[mb_xy]); if (FRAME_MBAFF) { ff_h264_filter_mb(h, mb_x, mb_y, dest_y, dest_cb, dest_cr, @@ -3978,9 +4050,9 @@ static void predict_field_decoding_flag(H264Context *h) { const int mb_xy = h->mb_x + h->mb_y * h->mb_stride; int mb_type = (h->slice_table[mb_xy - 1] == h->slice_num) ? - h->cur_pic.f.mb_type[mb_xy - 1] : + h->cur_pic.mb_type[mb_xy - 1] : (h->slice_table[mb_xy - h->mb_stride] == h->slice_num) ? - h->cur_pic.f.mb_type[mb_xy - h->mb_stride] : 0; + h->cur_pic.mb_type[mb_xy - h->mb_stride] : 0; h->mb_mbaff = h->mb_field_decoding_flag = IS_INTERLACED(mb_type) ? 1 : 0; } @@ -4014,7 +4086,7 @@ static void decode_finish_row(H264Context *h) if (h->droppable) return; - ff_thread_report_progress(&h->cur_pic_ptr->f, top + height - 1, + ff_thread_report_progress(&h->cur_pic_ptr->tf, top + height - 1, h->picture_structure == PICT_BOTTOM_FIELD); } @@ -4513,9 +4585,8 @@ again: end: /* clean up */ - if (h->cur_pic_ptr && h->cur_pic_ptr->owner2 == h && - !h->droppable) { - ff_thread_report_progress(&h->cur_pic_ptr->f, INT_MAX, + if (h->cur_pic_ptr && !h->droppable) { + ff_thread_report_progress(&h->cur_pic_ptr->tf, INT_MAX, h->picture_structure == PICT_BOTTOM_FIELD); } @@ -4543,6 +4614,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, H264Context *h = avctx->priv_data; AVFrame *pict = data; int buf_index = 0; + int ret; h->flags = avctx->flags; @@ -4571,8 +4643,9 @@ out: h->delayed_pic[i] = h->delayed_pic[i + 1]; if (out) { + if ((ret = av_frame_ref(pict, &out->f)) < 0) + return ret; *got_frame = 1; - *pict = out->f; } return buf_index; @@ -4605,8 +4678,9 @@ out: /* Wait for second field. */ *got_frame = 0; } else { + if ((ret = av_frame_ref(pict, &h->next_output_pic->f)) < 0) + return ret; *got_frame = 1; - *pict = h->next_output_pic->f; } } @@ -4635,13 +4709,15 @@ static av_cold int h264_decode_end(AVCodecContext *avctx) ff_h264_free_context(h); - if (h->DPB && !h->avctx->internal->is_copy) { - for (i = 0; i < h->picture_count; i++) { - free_picture(h, &h->DPB[i]); + if (h->DPB) { + for (i = 0; i < MAX_PICTURE_COUNT; i++) { + unref_picture(h, &h->DPB[i]); } } av_freep(&h->DPB); + unref_picture(h, &h->cur_pic); + return 0; } diff --git a/libavcodec/h264.h b/libavcodec/h264.h index e3e28911f5..e33f37e359 100644 --- a/libavcodec/h264.h +++ b/libavcodec/h264.h @@ -266,8 +266,6 @@ typedef struct H264Context { Picture *DPB; Picture *cur_pic_ptr; Picture cur_pic; - int picture_count; - int picture_range_start, picture_range_end; int pixel_shift; ///< 0 for 8-bit H264, 1 for high-bit-depth H264 int chroma_qp[2]; // QPc @@ -621,6 +619,11 @@ typedef struct H264Context { uint8_t *bipred_scratchpad; uint8_t *edge_emu_buffer; int16_t *dc_val_base; + + AVBufferPool *qscale_table_pool; + AVBufferPool *mb_type_pool; + AVBufferPool *motion_val_pool; + AVBufferPool *ref_index_pool; } H264Context; extern const uint8_t ff_h264_chroma_qp[3][QP_MAX_NUM + 1]; ///< One chroma qp table for each supported bit depth (8, 9, 10). @@ -876,7 +879,7 @@ static av_always_inline void write_back_motion_list(H264Context *h, int b_xy, int b8_xy, int mb_type, int list) { - int16_t(*mv_dst)[2] = &h->cur_pic.f.motion_val[list][b_xy]; + int16_t(*mv_dst)[2] = &h->cur_pic.motion_val[list][b_xy]; int16_t(*mv_src)[2] = &h->mv_cache[list][scan8[0]]; AV_COPY128(mv_dst + 0 * b_stride, mv_src + 8 * 0); AV_COPY128(mv_dst + 1 * b_stride, mv_src + 8 * 1); @@ -897,7 +900,7 @@ static av_always_inline void write_back_motion_list(H264Context *h, } { - int8_t *ref_index = &h->cur_pic.f.ref_index[list][b8_xy]; + int8_t *ref_index = &h->cur_pic.ref_index[list][b8_xy]; int8_t *ref_cache = h->ref_cache[list]; ref_index[0 + 0 * 2] = ref_cache[scan8[0]]; ref_index[1 + 0 * 2] = ref_cache[scan8[4]]; @@ -915,7 +918,7 @@ static av_always_inline void write_back_motion(H264Context *h, int mb_type) if (USES_LIST(mb_type, 0)) { write_back_motion_list(h, b_stride, b_xy, b8_xy, mb_type, 0); } else { - fill_rectangle(&h->cur_pic.f.ref_index[0][b8_xy], + fill_rectangle(&h->cur_pic.ref_index[0][b8_xy], 2, 2, 2, (uint8_t)LIST_NOT_USED, 1); } if (USES_LIST(mb_type, 1)) diff --git a/libavcodec/h264_cabac.c b/libavcodec/h264_cabac.c index 4effc7d5e0..12eb2c7b22 100644 --- a/libavcodec/h264_cabac.c +++ b/libavcodec/h264_cabac.c @@ -1283,8 +1283,8 @@ static int decode_cabac_field_decoding_flag(H264Context *h) { unsigned long ctx = 0; - ctx += h->mb_field_decoding_flag & !!h->mb_x; //for FMO:(s->current_picture.f.mb_type[mba_xy] >> 7) & (h->slice_table[mba_xy] == h->slice_num); - ctx += (h->cur_pic.f.mb_type[mbb_xy] >> 7) & (h->slice_table[mbb_xy] == h->slice_num); + ctx += h->mb_field_decoding_flag & !!h->mb_x; //for FMO:(s->current_picture.mb_type[mba_xy] >> 7) & (h->slice_table[mba_xy] == h->slice_num); + ctx += (h->cur_pic.mb_type[mbb_xy] >> 7) & (h->slice_table[mbb_xy] == h->slice_num); return get_cabac_noinline( &h->cabac, &(h->cabac_state+70)[ctx] ); } @@ -1328,13 +1328,13 @@ static int decode_cabac_mb_skip( H264Context *h, int mb_x, int mb_y ) { mba_xy = mb_xy - 1; if( (mb_y&1) && h->slice_table[mba_xy] == h->slice_num - && MB_FIELD == !!IS_INTERLACED( h->cur_pic.f.mb_type[mba_xy] ) ) + && MB_FIELD == !!IS_INTERLACED( h->cur_pic.mb_type[mba_xy] ) ) mba_xy += h->mb_stride; if( MB_FIELD ){ mbb_xy = mb_xy - h->mb_stride; if( !(mb_y&1) && h->slice_table[mbb_xy] == h->slice_num - && IS_INTERLACED( h->cur_pic.f.mb_type[mbb_xy] ) ) + && IS_INTERLACED( h->cur_pic.mb_type[mbb_xy] ) ) mbb_xy -= h->mb_stride; }else mbb_xy = mb_x + (mb_y-1)*h->mb_stride; @@ -1344,9 +1344,9 @@ static int decode_cabac_mb_skip( H264Context *h, int mb_x, int mb_y ) { mbb_xy = mb_xy - (h->mb_stride << FIELD_PICTURE); } - if( h->slice_table[mba_xy] == h->slice_num && !IS_SKIP(h->cur_pic.f.mb_type[mba_xy] )) + if( h->slice_table[mba_xy] == h->slice_num && !IS_SKIP(h->cur_pic.mb_type[mba_xy] )) ctx++; - if( h->slice_table[mbb_xy] == h->slice_num && !IS_SKIP(h->cur_pic.f.mb_type[mbb_xy] )) + if( h->slice_table[mbb_xy] == h->slice_num && !IS_SKIP(h->cur_pic.mb_type[mbb_xy] )) ctx++; if( h->slice_type_nos == AV_PICTURE_TYPE_B ) @@ -1893,7 +1893,7 @@ int ff_h264_decode_mb_cabac(H264Context *h) { /* read skip flags */ if( skip ) { if( FRAME_MBAFF && (h->mb_y&1)==0 ){ - h->cur_pic.f.mb_type[mb_xy] = MB_TYPE_SKIP; + h->cur_pic.mb_type[mb_xy] = MB_TYPE_SKIP; h->next_mb_skipped = decode_cabac_mb_skip( h, h->mb_x, h->mb_y+1 ); if(!h->next_mb_skipped) h->mb_mbaff = h->mb_field_decoding_flag = decode_cabac_field_decoding_flag(h); @@ -2012,10 +2012,10 @@ decode_intra_mb: h->cbp_table[mb_xy] = 0xf7ef; h->chroma_pred_mode_table[mb_xy] = 0; // In deblocking, the quantizer is 0 - h->cur_pic.f.qscale_table[mb_xy] = 0; + h->cur_pic.qscale_table[mb_xy] = 0; // All coeffs are present memset(h->non_zero_count[mb_xy], 16, 48); - h->cur_pic.f.mb_type[mb_xy] = mb_type; + h->cur_pic.mb_type[mb_xy] = mb_type; h->last_qscale_diff = 0; return 0; } @@ -2309,7 +2309,7 @@ decode_intra_mb: AV_WN32A(&nnz_cache[4+8*10], top_empty); } } - h->cur_pic.f.mb_type[mb_xy] = mb_type; + h->cur_pic.mb_type[mb_xy] = mb_type; if( cbp || IS_INTRA16x16( mb_type ) ) { const uint8_t *scan, *scan8x8; @@ -2411,7 +2411,7 @@ decode_intra_mb: h->last_qscale_diff = 0; } - h->cur_pic.f.qscale_table[mb_xy] = h->qscale; + h->cur_pic.qscale_table[mb_xy] = h->qscale; write_back_non_zero_count(h); return 0; diff --git a/libavcodec/h264_cavlc.c b/libavcodec/h264_cavlc.c index 4b44cbefa9..be7d2e9698 100644 --- a/libavcodec/h264_cavlc.c +++ b/libavcodec/h264_cavlc.c @@ -769,11 +769,11 @@ decode_intra_mb: skip_bits_long(&h->gb, mb_size); // In deblocking, the quantizer is 0 - h->cur_pic.f.qscale_table[mb_xy] = 0; + h->cur_pic.qscale_table[mb_xy] = 0; // All coeffs are present memset(h->non_zero_count[mb_xy], 16, 48); - h->cur_pic.f.mb_type[mb_xy] = mb_type; + h->cur_pic.mb_type[mb_xy] = mb_type; return 0; } @@ -1068,7 +1068,7 @@ decode_intra_mb: } h->cbp= h->cbp_table[mb_xy]= cbp; - h->cur_pic.f.mb_type[mb_xy] = mb_type; + h->cur_pic.mb_type[mb_xy] = mb_type; if(cbp || IS_INTRA16x16(mb_type)){ int i4x4, i8x8, chroma_idx; @@ -1168,7 +1168,7 @@ decode_intra_mb: fill_rectangle(&h->non_zero_count_cache[scan8[16]], 4, 4, 8, 0, 1); fill_rectangle(&h->non_zero_count_cache[scan8[32]], 4, 4, 8, 0, 1); } - h->cur_pic.f.qscale_table[mb_xy] = h->qscale; + h->cur_pic.qscale_table[mb_xy] = h->qscale; write_back_non_zero_count(h); return 0; diff --git a/libavcodec/h264_direct.c b/libavcodec/h264_direct.c index 9d8758edfc..0e81280612 100644 --- a/libavcodec/h264_direct.c +++ b/libavcodec/h264_direct.c @@ -87,7 +87,7 @@ static void fill_colmap(H264Context *h, int map[2][16+32], int list, int field, poc= (poc&~3) + rfield + 1; for(j=start; jref_list[0][j].frame_num + (h->ref_list[0][j].f.reference & 3) == poc) { + if (4 * h->ref_list[0][j].frame_num + (h->ref_list[0][j].reference & 3) == poc) { int cur_ref= mbafi ? (j-16)^field : j; if (ref1->mbaff) map[list][2 * old_ref + (rfield^field) + 16] = cur_ref; @@ -105,12 +105,12 @@ void ff_h264_direct_ref_list_init(H264Context * const h){ Picture * const cur = h->cur_pic_ptr; int list, j, field; int sidx= (h->picture_structure&1)^1; - int ref1sidx = (ref1->f.reference&1)^1; + int ref1sidx = (ref1->reference&1)^1; for(list=0; list<2; list++){ cur->ref_count[sidx][list] = h->ref_count[list]; for(j=0; jref_count[list]; j++) - cur->ref_poc[sidx][list][j] = 4 * h->ref_list[list][j].frame_num + (h->ref_list[list][j].f.reference & 3); + cur->ref_poc[sidx][list][j] = 4 * h->ref_list[list][j].frame_num + (h->ref_list[list][j].reference & 3); } if(h->picture_structure == PICT_FRAME){ @@ -126,8 +126,8 @@ void ff_h264_direct_ref_list_init(H264Context * const h){ int *col_poc = h->ref_list[1]->field_poc; h->col_parity= (FFABS(col_poc[0] - cur_poc) >= FFABS(col_poc[1] - cur_poc)); ref1sidx=sidx= h->col_parity; - } else if (!(h->picture_structure & h->ref_list[1][0].f.reference) && !h->ref_list[1][0].mbaff) { // FL -> FL & differ parity - h->col_fieldoff = 2 * h->ref_list[1][0].f.reference - 3; + } else if (!(h->picture_structure & h->ref_list[1][0].reference) && !h->ref_list[1][0].mbaff) { // FL -> FL & differ parity + h->col_fieldoff = 2 * h->ref_list[1][0].reference - 3; } if (h->slice_type_nos != AV_PICTURE_TYPE_B || h->direct_spatial_mv_pred) @@ -143,7 +143,7 @@ void ff_h264_direct_ref_list_init(H264Context * const h){ static void await_reference_mb_row(H264Context * const h, Picture *ref, int mb_y) { - int ref_field = ref->f.reference - 1; + int ref_field = ref->reference - 1; int ref_field_picture = ref->field_picture; int ref_height = 16*h->mb_height >> ref_field_picture; @@ -153,7 +153,7 @@ static void await_reference_mb_row(H264Context * const h, Picture *ref, int mb_y //FIXME it can be safe to access mb stuff //even if pixels aren't deblocked yet - ff_thread_await_progress(&ref->f, + ff_thread_await_progress(&ref->tf, FFMIN(16 * mb_y >> ref_field_picture, ref_height - 1), ref_field_picture && ref_field); } @@ -172,7 +172,7 @@ static void pred_spatial_direct_motion(H264Context * const h, int *mb_type){ int mv[2]; int list; - assert(h->ref_list[1][0].f.reference & 3); + assert(h->ref_list[1][0].reference & 3); await_reference_mb_row(h, &h->ref_list[1][0], h->mb_y + !!IS_INTERLACED(*mb_type)); @@ -234,7 +234,7 @@ static void pred_spatial_direct_motion(H264Context * const h, int *mb_type){ return; } - if (IS_INTERLACED(h->ref_list[1][0].f.mb_type[mb_xy])) { // AFL/AFR/FR/FL -> AFL/FL + if (IS_INTERLACED(h->ref_list[1][0].mb_type[mb_xy])) { // AFL/AFR/FR/FL -> AFL/FL if (!IS_INTERLACED(*mb_type)) { // AFR/FR -> AFL/FL mb_y = (h->mb_y&~1) + h->col_parity; mb_xy= h->mb_x + ((h->mb_y&~1) + h->col_parity)*h->mb_stride; @@ -248,8 +248,8 @@ static void pred_spatial_direct_motion(H264Context * const h, int *mb_type){ if(IS_INTERLACED(*mb_type)){ // AFL /FL -> AFR/FR mb_y = h->mb_y&~1; mb_xy= h->mb_x + (h->mb_y&~1)*h->mb_stride; - mb_type_col[0] = h->ref_list[1][0].f.mb_type[mb_xy]; - mb_type_col[1] = h->ref_list[1][0].f.mb_type[mb_xy + h->mb_stride]; + mb_type_col[0] = h->ref_list[1][0].mb_type[mb_xy]; + mb_type_col[1] = h->ref_list[1][0].mb_type[mb_xy + h->mb_stride]; b8_stride = 2+4*h->mb_stride; b4_stride *= 6; if (IS_INTERLACED(mb_type_col[0]) != IS_INTERLACED(mb_type_col[1])) { @@ -268,7 +268,7 @@ static void pred_spatial_direct_motion(H264Context * const h, int *mb_type){ }else{ // AFR/FR -> AFR/FR single_col: mb_type_col[0] = - mb_type_col[1] = h->ref_list[1][0].f.mb_type[mb_xy]; + mb_type_col[1] = h->ref_list[1][0].mb_type[mb_xy]; sub_mb_type |= MB_TYPE_16x16|MB_TYPE_DIRECT2; /* B_SUB_8x8 */ if(!is_b8x8 && (mb_type_col[0] & MB_TYPE_16x16_OR_INTRA)){ @@ -288,10 +288,10 @@ single_col: await_reference_mb_row(h, &h->ref_list[1][0], mb_y); - l1mv0 = &h->ref_list[1][0].f.motion_val[0][h->mb2b_xy [mb_xy]]; - l1mv1 = &h->ref_list[1][0].f.motion_val[1][h->mb2b_xy [mb_xy]]; - l1ref0 = &h->ref_list[1][0].f.ref_index [0][4 * mb_xy]; - l1ref1 = &h->ref_list[1][0].f.ref_index [1][4 * mb_xy]; + l1mv0 = &h->ref_list[1][0].motion_val[0][h->mb2b_xy [mb_xy]]; + l1mv1 = &h->ref_list[1][0].motion_val[1][h->mb2b_xy [mb_xy]]; + l1ref0 = &h->ref_list[1][0].ref_index [0][4 * mb_xy]; + l1ref1 = &h->ref_list[1][0].ref_index [1][4 * mb_xy]; if(!b8_stride){ if(h->mb_y&1){ l1ref0 += 2; @@ -419,11 +419,11 @@ static void pred_temp_direct_motion(H264Context * const h, int *mb_type){ unsigned int sub_mb_type; int i8, i4; - assert(h->ref_list[1][0].f.reference & 3); + assert(h->ref_list[1][0].reference & 3); await_reference_mb_row(h, &h->ref_list[1][0], h->mb_y + !!IS_INTERLACED(*mb_type)); - if (IS_INTERLACED(h->ref_list[1][0].f.mb_type[mb_xy])) { // AFL/AFR/FR/FL -> AFL/FL + if (IS_INTERLACED(h->ref_list[1][0].mb_type[mb_xy])) { // AFL/AFR/FR/FL -> AFL/FL if (!IS_INTERLACED(*mb_type)) { // AFR/FR -> AFL/FL mb_y = (h->mb_y&~1) + h->col_parity; mb_xy= h->mb_x + ((h->mb_y&~1) + h->col_parity)*h->mb_stride; @@ -437,8 +437,8 @@ static void pred_temp_direct_motion(H264Context * const h, int *mb_type){ if(IS_INTERLACED(*mb_type)){ // AFL /FL -> AFR/FR mb_y = h->mb_y&~1; mb_xy= h->mb_x + (h->mb_y&~1)*h->mb_stride; - mb_type_col[0] = h->ref_list[1][0].f.mb_type[mb_xy]; - mb_type_col[1] = h->ref_list[1][0].f.mb_type[mb_xy + h->mb_stride]; + mb_type_col[0] = h->ref_list[1][0].mb_type[mb_xy]; + mb_type_col[1] = h->ref_list[1][0].mb_type[mb_xy + h->mb_stride]; b8_stride = 2+4*h->mb_stride; b4_stride *= 6; if (IS_INTERLACED(mb_type_col[0]) != IS_INTERLACED(mb_type_col[1])) { @@ -458,7 +458,7 @@ static void pred_temp_direct_motion(H264Context * const h, int *mb_type){ }else{ // AFR/FR -> AFR/FR single_col: mb_type_col[0] = - mb_type_col[1] = h->ref_list[1][0].f.mb_type[mb_xy]; + mb_type_col[1] = h->ref_list[1][0].mb_type[mb_xy]; sub_mb_type = MB_TYPE_16x16|MB_TYPE_P0L0|MB_TYPE_P0L1|MB_TYPE_DIRECT2; /* B_SUB_8x8 */ if(!is_b8x8 && (mb_type_col[0] & MB_TYPE_16x16_OR_INTRA)){ @@ -478,10 +478,10 @@ single_col: await_reference_mb_row(h, &h->ref_list[1][0], mb_y); - l1mv0 = &h->ref_list[1][0].f.motion_val[0][h->mb2b_xy [mb_xy]]; - l1mv1 = &h->ref_list[1][0].f.motion_val[1][h->mb2b_xy [mb_xy]]; - l1ref0 = &h->ref_list[1][0].f.ref_index [0][4 * mb_xy]; - l1ref1 = &h->ref_list[1][0].f.ref_index [1][4 * mb_xy]; + l1mv0 = &h->ref_list[1][0].motion_val[0][h->mb2b_xy [mb_xy]]; + l1mv1 = &h->ref_list[1][0].motion_val[1][h->mb2b_xy [mb_xy]]; + l1ref0 = &h->ref_list[1][0].ref_index [0][4 * mb_xy]; + l1ref1 = &h->ref_list[1][0].ref_index [1][4 * mb_xy]; if(!b8_stride){ if(h->mb_y&1){ l1ref0 += 2; diff --git a/libavcodec/h264_loopfilter.c b/libavcodec/h264_loopfilter.c index 929997c778..2e4683d8e3 100644 --- a/libavcodec/h264_loopfilter.c +++ b/libavcodec/h264_loopfilter.c @@ -256,10 +256,10 @@ static av_always_inline void h264_filter_mb_fast_internal(H264Context *h, int a = h->slice_alpha_c0_offset - qp_bd_offset; int b = h->slice_beta_offset - qp_bd_offset; - int mb_type = h->cur_pic.f.mb_type[mb_xy]; - int qp = h->cur_pic.f.qscale_table[mb_xy]; - int qp0 = h->cur_pic.f.qscale_table[mb_xy - 1]; - int qp1 = h->cur_pic.f.qscale_table[h->top_mb_xy]; + int mb_type = h->cur_pic.mb_type[mb_xy]; + int qp = h->cur_pic.qscale_table[mb_xy]; + int qp0 = h->cur_pic.qscale_table[mb_xy - 1]; + int qp1 = h->cur_pic.qscale_table[h->top_mb_xy]; int qpc = get_chroma_qp( h, 0, qp ); int qpc0 = get_chroma_qp( h, 0, qp0 ); int qpc1 = get_chroma_qp( h, 0, qp1 ); @@ -497,10 +497,10 @@ static av_always_inline void filter_mb_dir(H264Context *h, int mb_x, int mb_y, u for(j=0; j<2; j++, mbn_xy += h->mb_stride){ DECLARE_ALIGNED(8, int16_t, bS)[4]; int qp; - if (IS_INTRA(mb_type | h->cur_pic.f.mb_type[mbn_xy])) { + if (IS_INTRA(mb_type | h->cur_pic.mb_type[mbn_xy])) { AV_WN64A(bS, 0x0003000300030003ULL); } else { - if (!CABAC && IS_8x8DCT(h->cur_pic.f.mb_type[mbn_xy])) { + if (!CABAC && IS_8x8DCT(h->cur_pic.mb_type[mbn_xy])) { bS[0]= 1+((h->cbp_table[mbn_xy] & 0x4000)||h->non_zero_count_cache[scan8[0]+0]); bS[1]= 1+((h->cbp_table[mbn_xy] & 0x4000)||h->non_zero_count_cache[scan8[0]+1]); bS[2]= 1+((h->cbp_table[mbn_xy] & 0x8000)||h->non_zero_count_cache[scan8[0]+2]); @@ -515,12 +515,12 @@ static av_always_inline void filter_mb_dir(H264Context *h, int mb_x, int mb_y, u } // Do not use s->qscale as luma quantizer because it has not the same // value in IPCM macroblocks. - qp = (h->cur_pic.f.qscale_table[mb_xy] + h->cur_pic.f.qscale_table[mbn_xy] + 1) >> 1; + qp = (h->cur_pic.qscale_table[mb_xy] + h->cur_pic.qscale_table[mbn_xy] + 1) >> 1; tprintf(h->avctx, "filter mb:%d/%d dir:%d edge:%d, QPy:%d ls:%d uvls:%d", mb_x, mb_y, dir, edge, qp, tmp_linesize, tmp_uvlinesize); { int i; for (i = 0; i < 4; i++) tprintf(h->avctx, " bS[%d]:%d", i, bS[i]); tprintf(h->avctx, "\n"); } filter_mb_edgeh( &img_y[j*linesize], tmp_linesize, bS, qp, a, b, h, 0 ); - chroma_qp_avg[0] = (h->chroma_qp[0] + get_chroma_qp(h, 0, h->cur_pic.f.qscale_table[mbn_xy]) + 1) >> 1; - chroma_qp_avg[1] = (h->chroma_qp[1] + get_chroma_qp(h, 1, h->cur_pic.f.qscale_table[mbn_xy]) + 1) >> 1; + chroma_qp_avg[0] = (h->chroma_qp[0] + get_chroma_qp(h, 0, h->cur_pic.qscale_table[mbn_xy]) + 1) >> 1; + chroma_qp_avg[1] = (h->chroma_qp[1] + get_chroma_qp(h, 1, h->cur_pic.qscale_table[mbn_xy]) + 1) >> 1; if (chroma) { if (chroma444) { filter_mb_edgeh (&img_cb[j*uvlinesize], tmp_uvlinesize, bS, chroma_qp_avg[0], a, b, h, 0); @@ -580,10 +580,10 @@ static av_always_inline void filter_mb_dir(H264Context *h, int mb_x, int mb_y, u // Do not use s->qscale as luma quantizer because it has not the same // value in IPCM macroblocks. if(bS[0]+bS[1]+bS[2]+bS[3]){ - qp = (h->cur_pic.f.qscale_table[mb_xy] + h->cur_pic.f.qscale_table[mbm_xy] + 1) >> 1; + qp = (h->cur_pic.qscale_table[mb_xy] + h->cur_pic.qscale_table[mbm_xy] + 1) >> 1; tprintf(h->avctx, "filter mb:%d/%d dir:%d edge:%d, QPy:%d ls:%d uvls:%d", mb_x, mb_y, dir, edge, qp, linesize, uvlinesize); - chroma_qp_avg[0] = (h->chroma_qp[0] + get_chroma_qp(h, 0, h->cur_pic.f.qscale_table[mbm_xy]) + 1) >> 1; - chroma_qp_avg[1] = (h->chroma_qp[1] + get_chroma_qp(h, 1, h->cur_pic.f.qscale_table[mbm_xy]) + 1) >> 1; + chroma_qp_avg[0] = (h->chroma_qp[0] + get_chroma_qp(h, 0, h->cur_pic.qscale_table[mbm_xy]) + 1) >> 1; + chroma_qp_avg[1] = (h->chroma_qp[1] + get_chroma_qp(h, 1, h->cur_pic.qscale_table[mbm_xy]) + 1) >> 1; if( dir == 0 ) { filter_mb_edgev( &img_y[0], linesize, bS, qp, a, b, h, 1 ); if (chroma) { @@ -663,7 +663,7 @@ static av_always_inline void filter_mb_dir(H264Context *h, int mb_x, int mb_y, u /* Filter edge */ // Do not use s->qscale as luma quantizer because it has not the same // value in IPCM macroblocks. - qp = h->cur_pic.f.qscale_table[mb_xy]; + qp = h->cur_pic.qscale_table[mb_xy]; tprintf(h->avctx, "filter mb:%d/%d dir:%d edge:%d, QPy:%d ls:%d uvls:%d", mb_x, mb_y, dir, edge, qp, linesize, uvlinesize); if( dir == 0 ) { filter_mb_edgev( &img_y[4*edge << h->pixel_shift], linesize, bS, qp, a, b, h, 0 ); @@ -702,7 +702,7 @@ static av_always_inline void filter_mb_dir(H264Context *h, int mb_x, int mb_y, u void ff_h264_filter_mb( H264Context *h, int mb_x, int mb_y, uint8_t *img_y, uint8_t *img_cb, uint8_t *img_cr, unsigned int linesize, unsigned int uvlinesize) { const int mb_xy= mb_x + mb_y*h->mb_stride; - const int mb_type = h->cur_pic.f.mb_type[mb_xy]; + const int mb_type = h->cur_pic.mb_type[mb_xy]; const int mvy_limit = IS_INTERLACED(mb_type) ? 2 : 4; int first_vertical_edge_done = 0; av_unused int dir; @@ -758,9 +758,9 @@ void ff_h264_filter_mb( H264Context *h, int mb_x, int mb_y, uint8_t *img_y, uint } } - mb_qp = h->cur_pic.f.qscale_table[mb_xy]; - mbn0_qp = h->cur_pic.f.qscale_table[h->left_mb_xy[0]]; - mbn1_qp = h->cur_pic.f.qscale_table[h->left_mb_xy[1]]; + mb_qp = h->cur_pic.qscale_table[mb_xy]; + mbn0_qp = h->cur_pic.qscale_table[h->left_mb_xy[0]]; + mbn1_qp = h->cur_pic.qscale_table[h->left_mb_xy[1]]; qp[0] = ( mb_qp + mbn0_qp + 1 ) >> 1; bqp[0] = ( get_chroma_qp( h, 0, mb_qp ) + get_chroma_qp( h, 0, mbn0_qp ) + 1 ) >> 1; diff --git a/libavcodec/h264_mb_template.c b/libavcodec/h264_mb_template.c index b596567429..a39d4c9ca0 100644 --- a/libavcodec/h264_mb_template.c +++ b/libavcodec/h264_mb_template.c @@ -43,7 +43,7 @@ static av_noinline void FUNC(hl_decode_mb)(H264Context *h) const int mb_x = h->mb_x; const int mb_y = h->mb_y; const int mb_xy = h->mb_xy; - const int mb_type = h->cur_pic.f.mb_type[mb_xy]; + const int mb_type = h->cur_pic.mb_type[mb_xy]; uint8_t *dest_y, *dest_cb, *dest_cr; int linesize, uvlinesize /*dct_offset*/; int i, j; @@ -279,7 +279,7 @@ static av_noinline void FUNC(hl_decode_mb_444)(H264Context *h) const int mb_x = h->mb_x; const int mb_y = h->mb_y; const int mb_xy = h->mb_xy; - const int mb_type = h->cur_pic.f.mb_type[mb_xy]; + const int mb_type = h->cur_pic.mb_type[mb_xy]; uint8_t *dest[3]; int linesize; int i, j, p; diff --git a/libavcodec/h264_mc_template.c b/libavcodec/h264_mc_template.c index ad54558b91..dee02f5908 100644 --- a/libavcodec/h264_mc_template.c +++ b/libavcodec/h264_mc_template.c @@ -68,7 +68,7 @@ static void MCFUNC(hl_motion)(H264Context *h, uint8_t *dest_y, h264_biweight_func *weight_avg) { const int mb_xy = h->mb_xy; - const int mb_type = h->cur_pic.f.mb_type[mb_xy]; + const int mb_type = h->cur_pic.mb_type[mb_xy]; assert(IS_INTER(mb_type)); diff --git a/libavcodec/h264_mvpred.h b/libavcodec/h264_mvpred.h index b49ff31c15..a61ad20f66 100644 --- a/libavcodec/h264_mvpred.h +++ b/libavcodec/h264_mvpred.h @@ -48,15 +48,15 @@ static av_always_inline int fetch_diagonal_mv(H264Context *h, const int16_t **C, const int mb_type = mb_types[xy + (y4 >> 2) * h->mb_stride]; \ if (!USES_LIST(mb_type, list)) \ return LIST_NOT_USED; \ - mv = h->cur_pic_ptr->f.motion_val[list][h->mb2b_xy[xy] + 3 + y4 * h->b_stride]; \ + mv = h->cur_pic_ptr->motion_val[list][h->mb2b_xy[xy] + 3 + y4 * h->b_stride]; \ h->mv_cache[list][scan8[0] - 2][0] = mv[0]; \ h->mv_cache[list][scan8[0] - 2][1] = mv[1] MV_OP; \ - return h->cur_pic_ptr->f.ref_index[list][4 * xy + 1 + (y4 & ~1)] REF_OP; + return h->cur_pic_ptr->ref_index[list][4 * xy + 1 + (y4 & ~1)] REF_OP; if (topright_ref == PART_NOT_AVAILABLE && i >= scan8[0] + 8 && (i & 7) == 4 && h->ref_cache[list][scan8[0] - 1] != PART_NOT_AVAILABLE) { - const uint32_t *mb_types = h->cur_pic_ptr->f.mb_type; + const uint32_t *mb_types = h->cur_pic_ptr->mb_type; const int16_t *mv; AV_ZERO32(h->mv_cache[list][scan8[0] - 2]); *C = h->mv_cache[list][scan8[0] - 2]; @@ -253,8 +253,8 @@ static av_always_inline void pred_pskip_motion(H264Context *const h) { DECLARE_ALIGNED(4, static const int16_t, zeromv)[2] = { 0 }; DECLARE_ALIGNED(4, int16_t, mvbuf)[3][2]; - int8_t *ref = h->cur_pic.f.ref_index[0]; - int16_t(*mv)[2] = h->cur_pic.f.motion_val[0]; + int8_t *ref = h->cur_pic.ref_index[0]; + int16_t(*mv)[2] = h->cur_pic.motion_val[0]; int top_ref, left_ref, diagonal_ref, match_count, mx, my; const int16_t *A, *B, *C; int b_stride = h->b_stride; @@ -370,7 +370,7 @@ static void fill_decode_neighbors(H264Context *h, int mb_type) left_xy[LBOT] = left_xy[LTOP] = mb_xy - 1; h->left_block = left_block_options[0]; if (FRAME_MBAFF) { - const int left_mb_field_flag = IS_INTERLACED(h->cur_pic.f.mb_type[mb_xy - 1]); + const int left_mb_field_flag = IS_INTERLACED(h->cur_pic.mb_type[mb_xy - 1]); const int curr_mb_field_flag = IS_INTERLACED(mb_type); if (h->mb_y & 1) { if (left_mb_field_flag != curr_mb_field_flag) { @@ -388,9 +388,9 @@ static void fill_decode_neighbors(H264Context *h, int mb_type) } } else { if (curr_mb_field_flag) { - topleft_xy += h->mb_stride & (((h->cur_pic.f.mb_type[top_xy - 1] >> 7) & 1) - 1); - topright_xy += h->mb_stride & (((h->cur_pic.f.mb_type[top_xy + 1] >> 7) & 1) - 1); - top_xy += h->mb_stride & (((h->cur_pic.f.mb_type[top_xy] >> 7) & 1) - 1); + topleft_xy += h->mb_stride & (((h->cur_pic.mb_type[top_xy - 1] >> 7) & 1) - 1); + topright_xy += h->mb_stride & (((h->cur_pic.mb_type[top_xy + 1] >> 7) & 1) - 1); + top_xy += h->mb_stride & (((h->cur_pic.mb_type[top_xy] >> 7) & 1) - 1); } if (left_mb_field_flag != curr_mb_field_flag) { if (curr_mb_field_flag) { @@ -410,11 +410,11 @@ static void fill_decode_neighbors(H264Context *h, int mb_type) h->left_mb_xy[LBOT] = left_xy[LBOT]; //FIXME do we need all in the context? - h->topleft_type = h->cur_pic.f.mb_type[topleft_xy]; - h->top_type = h->cur_pic.f.mb_type[top_xy]; - h->topright_type = h->cur_pic.f.mb_type[topright_xy]; - h->left_type[LTOP] = h->cur_pic.f.mb_type[left_xy[LTOP]]; - h->left_type[LBOT] = h->cur_pic.f.mb_type[left_xy[LBOT]]; + h->topleft_type = h->cur_pic.mb_type[topleft_xy]; + h->top_type = h->cur_pic.mb_type[top_xy]; + h->topright_type = h->cur_pic.mb_type[topright_xy]; + h->left_type[LTOP] = h->cur_pic.mb_type[left_xy[LTOP]]; + h->left_type[LBOT] = h->cur_pic.mb_type[left_xy[LBOT]]; if (FMO) { if (h->slice_table[topleft_xy] != h->slice_num) @@ -480,7 +480,7 @@ static void fill_decode_caches(H264Context *h, int mb_type) h->left_samples_available &= 0xFF5F; } } else { - int left_typei = h->cur_pic.f.mb_type[left_xy[LTOP] + h->mb_stride]; + int left_typei = h->cur_pic.mb_type[left_xy[LTOP] + h->mb_stride]; assert(left_xy[LTOP] == left_xy[LBOT]); if (!((left_typei & type_mask) && (left_type[LTOP] & type_mask))) { @@ -602,9 +602,9 @@ static void fill_decode_caches(H264Context *h, int mb_type) int b_stride = h->b_stride; for (list = 0; list < h->list_count; list++) { int8_t *ref_cache = &h->ref_cache[list][scan8[0]]; - int8_t *ref = h->cur_pic.f.ref_index[list]; + int8_t *ref = h->cur_pic.ref_index[list]; int16_t(*mv_cache)[2] = &h->mv_cache[list][scan8[0]]; - int16_t(*mv)[2] = h->cur_pic.f.motion_val[list]; + int16_t(*mv)[2] = h->cur_pic.motion_val[list]; if (!USES_LIST(mb_type, list)) continue; assert(!(IS_DIRECT(mb_type) && !h->direct_spatial_mv_pred)); @@ -821,8 +821,8 @@ static void av_unused decode_mb_skip(H264Context *h) } write_back_motion(h, mb_type); - h->cur_pic.f.mb_type[mb_xy] = mb_type; - h->cur_pic.f.qscale_table[mb_xy] = h->qscale; + h->cur_pic.mb_type[mb_xy] = mb_type; + h->cur_pic.qscale_table[mb_xy] = h->qscale; h->slice_table[mb_xy] = h->slice_num; h->prev_mb_skipped = 1; } diff --git a/libavcodec/h264_refs.c b/libavcodec/h264_refs.c index ead18c5680..2af47e3ed6 100644 --- a/libavcodec/h264_refs.c +++ b/libavcodec/h264_refs.c @@ -33,13 +33,20 @@ //#undef NDEBUG #include +#define COPY_PICTURE(dst, src) \ +do {\ + *(dst) = *(src);\ + (dst)->f.extended_data = (dst)->f.data;\ + (dst)->tf.f = &(dst)->f;\ +} while (0) + static void pic_as_field(Picture *pic, const int parity){ int i; for (i = 0; i < 4; ++i) { if (parity == PICT_BOTTOM_FIELD) pic->f.data[i] += pic->f.linesize[i]; - pic->f.reference = parity; + pic->reference = parity; pic->f.linesize[i] *= 2; } pic->poc= pic->field_poc[parity == PICT_BOTTOM_FIELD]; @@ -47,10 +54,10 @@ static void pic_as_field(Picture *pic, const int parity){ static int split_field_copy(Picture *dest, Picture *src, int parity, int id_add){ - int match = !!(src->f.reference & parity); + int match = !!(src->reference & parity); if (match) { - *dest = *src; + COPY_PICTURE(dest, src); if(parity != PICT_FRAME){ pic_as_field(dest, parity); dest->pic_id *= 2; @@ -66,9 +73,9 @@ static int build_def_list(Picture *def, Picture **in, int len, int is_long, int int index=0; while(i[0]f.reference & sel))) + while (i[0] < len && !(in[ i[0] ] && (in[ i[0] ]->reference & sel))) i[0]++; - while (i[1] < len && !(in[ i[1] ] && (in[ i[1] ]->f.reference & (sel^3)))) + while (i[1] < len && !(in[ i[1] ] && (in[ i[1] ]->reference & (sel^3)))) i[1]++; if(i[0] < len){ in[ i[0] ]->pic_id= is_long ? i[0] : in[ i[0] ]->frame_num; @@ -132,8 +139,12 @@ int ff_h264_fill_default_ref_list(H264Context *h){ if(lens[0] == lens[1] && lens[1] > 1){ for (i = 0; h->default_ref_list[0][i].f.data[0] == h->default_ref_list[1][i].f.data[0] && i < lens[0]; i++); - if(i == lens[0]) - FFSWAP(Picture, h->default_ref_list[1][0], h->default_ref_list[1][1]); + if (i == lens[0]) { + Picture tmp; + COPY_PICTURE(&tmp, &h->default_ref_list[1][0]); + COPY_PICTURE(&h->default_ref_list[1][0], &h->default_ref_list[1][1]); + COPY_PICTURE(&h->default_ref_list[1][1], &tmp); + } } }else{ len = build_def_list(h->default_ref_list[0] , h->short_ref, h->short_ref_count, 0, h->picture_structure); @@ -181,13 +192,14 @@ static int pic_num_extract(H264Context *h, int pic_num, int *structure){ } int ff_h264_decode_ref_pic_list_reordering(H264Context *h){ - int list, index, pic_structure; + int list, index, pic_structure, i; print_short_term(h); print_long_term(h); for(list=0; listlist_count; list++){ - memcpy(h->ref_list[list], h->default_ref_list[list], sizeof(Picture)*h->ref_count[list]); + for (i = 0; i < h->ref_count[list]; i++) + COPY_PICTURE(&h->ref_list[list][i], &h->default_ref_list[list][i]); if(get_bits1(&h->gb)){ int pred= h->curr_pic_num; @@ -224,11 +236,11 @@ int ff_h264_decode_ref_pic_list_reordering(H264Context *h){ for(i= h->short_ref_count-1; i>=0; i--){ ref = h->short_ref[i]; - assert(ref->f.reference); + assert(ref->reference); assert(!ref->long_ref); if( ref->frame_num == frame_num && - (ref->f.reference & pic_structure) + (ref->reference & pic_structure) ) break; } @@ -245,8 +257,8 @@ int ff_h264_decode_ref_pic_list_reordering(H264Context *h){ return -1; } ref = h->long_ref[long_idx]; - assert(!(ref && !ref->f.reference)); - if (ref && (ref->f.reference & pic_structure)) { + assert(!(ref && !ref->reference)); + if (ref && (ref->reference & pic_structure)) { ref->pic_id= pic_id; assert(ref->long_ref); i=0; @@ -264,9 +276,9 @@ int ff_h264_decode_ref_pic_list_reordering(H264Context *h){ break; } for(; i > index; i--){ - h->ref_list[list][i]= h->ref_list[list][i-1]; + COPY_PICTURE(&h->ref_list[list][i], &h->ref_list[list][i - 1]); } - h->ref_list[list][index]= *ref; + COPY_PICTURE(&h->ref_list[list][index], ref); if (FIELD_PICTURE){ pic_as_field(&h->ref_list[list][index], pic_structure); } @@ -283,7 +295,7 @@ int ff_h264_decode_ref_pic_list_reordering(H264Context *h){ if (!h->ref_list[list][index].f.data[0]) { av_log(h->avctx, AV_LOG_ERROR, "Missing reference picture\n"); if (h->default_ref_list[list][0].f.data[0]) - h->ref_list[list][index]= h->default_ref_list[list][0]; + COPY_PICTURE(&h->ref_list[list][index], &h->default_ref_list[list][0]); else return -1; } @@ -299,15 +311,15 @@ void ff_h264_fill_mbaff_ref_list(H264Context *h){ for(i=0; iref_count[list]; i++){ Picture *frame = &h->ref_list[list][i]; Picture *field = &h->ref_list[list][16+2*i]; - field[0] = *frame; + COPY_PICTURE(field, frame); for(j=0; j<3; j++) field[0].f.linesize[j] <<= 1; - field[0].f.reference = PICT_TOP_FIELD; + field[0].reference = PICT_TOP_FIELD; field[0].poc= field[0].field_poc[0]; - field[1] = field[0]; + COPY_PICTURE(field + 1, field); for(j=0; j<3; j++) field[1].f.data[j] += frame->f.linesize[j]; - field[1].f.reference = PICT_BOTTOM_FIELD; + field[1].reference = PICT_BOTTOM_FIELD; field[1].poc= field[1].field_poc[1]; h->luma_weight[16+2*i][list][0] = h->luma_weight[16+2*i+1][list][0] = h->luma_weight[i][list][0]; @@ -333,12 +345,12 @@ void ff_h264_fill_mbaff_ref_list(H264Context *h){ */ static inline int unreference_pic(H264Context *h, Picture *pic, int refmask){ int i; - if (pic->f.reference &= refmask) { + if (pic->reference &= refmask) { return 0; } else { for(i = 0; h->delayed_pic[i]; i++) if(pic == h->delayed_pic[i]){ - pic->f.reference = DELAYED_PIC_REF; + pic->reference = DELAYED_PIC_REF; break; } return 1; @@ -490,7 +502,7 @@ int ff_generate_sliding_window_mmcos(H264Context *h, int first_slice) if (h->short_ref_count && h->long_ref_count + h->short_ref_count == h->sps.ref_frame_count && - !(FIELD_PICTURE && !h->first_field && h->cur_pic_ptr->f.reference)) { + !(FIELD_PICTURE && !h->first_field && h->cur_pic_ptr->reference)) { mmco[0].opcode = MMCO_SHORT2UNUSED; mmco[0].short_pic_num = h->short_ref[h->short_ref_count - 1]->frame_num; mmco_index = 1; @@ -584,7 +596,7 @@ int ff_h264_execute_ref_pic_marking(H264Context *h, MMCO *mmco, int mmco_count){ h->long_ref_count++; } - h->cur_pic_ptr->f.reference |= h->picture_structure; + h->cur_pic_ptr->reference |= h->picture_structure; current_ref_assigned=1; break; case MMCO_SET_MAX_LONG: @@ -619,7 +631,7 @@ int ff_h264_execute_ref_pic_marking(H264Context *h, MMCO *mmco, int mmco_count){ */ if (h->short_ref_count && h->short_ref[0] == h->cur_pic_ptr) { /* Just mark the second field valid */ - h->cur_pic_ptr->f.reference = PICT_FRAME; + h->cur_pic_ptr->reference = PICT_FRAME; } else if (h->cur_pic_ptr->long_ref) { av_log(h->avctx, AV_LOG_ERROR, "illegal short term reference " "assignment for second field " @@ -638,7 +650,7 @@ int ff_h264_execute_ref_pic_marking(H264Context *h, MMCO *mmco, int mmco_count){ h->short_ref[0]= h->cur_pic_ptr; h->short_ref_count++; - h->cur_pic_ptr->f.reference |= h->picture_structure; + h->cur_pic_ptr->reference |= h->picture_structure; } } diff --git a/libavcodec/huffyuvdec.c b/libavcodec/huffyuvdec.c index 6aa7335bf9..7a58ba4688 100644 --- a/libavcodec/huffyuvdec.c +++ b/libavcodec/huffyuvdec.c @@ -241,7 +241,6 @@ static av_cold int decode_init(AVCodecContext *avctx) ff_huffyuv_common_init(avctx); memset(s->vlc, 0, 3 * sizeof(VLC)); - avctx->coded_frame = &s->picture; s->interlaced = s->height > 288; s->bgr32 = 1; @@ -337,7 +336,6 @@ static av_cold int decode_init_thread_copy(AVCodecContext *avctx) HYuvContext *s = avctx->priv_data; int i; - avctx->coded_frame= &s->picture; ff_huffyuv_alloc_temp(s); for (i = 0; i < 6; i++) @@ -443,7 +441,7 @@ static void decode_bgr_bitstream(HYuvContext *s, int count) } } -static void draw_slice(HYuvContext *s, int y) +static void draw_slice(HYuvContext *s, AVFrame *frame, int y) { int h, cy, i; int offset[AV_NUM_DATA_POINTERS]; @@ -460,14 +458,14 @@ static void draw_slice(HYuvContext *s, int y) cy = y; } - offset[0] = s->picture.linesize[0]*y; - offset[1] = s->picture.linesize[1]*cy; - offset[2] = s->picture.linesize[2]*cy; + offset[0] = frame->linesize[0] * y; + offset[1] = frame->linesize[1] * cy; + offset[2] = frame->linesize[2] * cy; for (i = 3; i < AV_NUM_DATA_POINTERS; i++) offset[i] = 0; emms_c(); - s->avctx->draw_horiz_band(s->avctx, &s->picture, offset, y, 3, h); + s->avctx->draw_horiz_band(s->avctx, frame, offset, y, 3, h); s->last_slice_end = y + h; } @@ -482,11 +480,10 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, const int width2 = s->width>>1; const int height = s->height; int fake_ystride, fake_ustride, fake_vstride; - AVFrame * const p = &s->picture; + ThreadFrame frame = { .f = data }; + AVFrame * const p = data; int table_size = 0; - AVFrame *picture = data; - av_fast_malloc(&s->bitstream_buffer, &s->bitstream_buffer_size, buf_size + FF_INPUT_BUFFER_PADDING_SIZE); @@ -497,11 +494,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, s->dsp.bswap_buf((uint32_t*)s->bitstream_buffer, (const uint32_t*)buf, buf_size / 4); - if (p->data[0]) - ff_thread_release_buffer(avctx, p); - - p->reference = 0; - if (ff_thread_get_buffer(avctx, p) < 0) { + if (ff_thread_get_buffer(avctx, &frame, 0) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return -1; } @@ -572,7 +565,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, if (y >= s->height) break; } - draw_slice(s, y); + draw_slice(s, p, y); ydst = p->data[0] + p->linesize[0]*y; udst = p->data[1] + p->linesize[1]*cy; @@ -594,7 +587,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, } } } - draw_slice(s, height); + draw_slice(s, p, height); break; case MEDIAN: @@ -651,7 +644,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, } if (y >= height) break; } - draw_slice(s, y); + draw_slice(s, p, y); decode_422_bitstream(s, width); @@ -666,7 +659,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, } } - draw_slice(s, height); + draw_slice(s, p, height); break; } } @@ -710,7 +703,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, } } // just 1 large slice as this is not possible in reverse order - draw_slice(s, height); + draw_slice(s, p, height); break; default: av_log(avctx, AV_LOG_ERROR, @@ -724,7 +717,6 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, } emms_c(); - *picture = *p; *got_frame = 1; return (get_bits_count(&s->gb) + 31) / 32 * 4 + table_size; @@ -735,9 +727,6 @@ static av_cold int decode_end(AVCodecContext *avctx) HYuvContext *s = avctx->priv_data; int i; - if (s->picture.data[0]) - avctx->release_buffer(avctx, &s->picture); - ff_huffyuv_common_end(s); av_freep(&s->bitstream_buffer); diff --git a/libavcodec/idcinvideo.c b/libavcodec/idcinvideo.c index 05cd673faa..9d34f3e247 100644 --- a/libavcodec/idcinvideo.c +++ b/libavcodec/idcinvideo.c @@ -66,7 +66,6 @@ typedef struct typedef struct IdcinContext { AVCodecContext *avctx; - AVFrame frame; const unsigned char *buf; int size; @@ -168,12 +167,10 @@ static av_cold int idcin_decode_init(AVCodecContext *avctx) huff_build_tree(s, i); } - avcodec_get_frame_defaults(&s->frame); - return 0; } -static void idcin_decode_vlcs(IdcinContext *s) +static void idcin_decode_vlcs(IdcinContext *s, AVFrame *frame) { hnode *hnodes; long x, y; @@ -182,8 +179,8 @@ static void idcin_decode_vlcs(IdcinContext *s) int bit_pos, node_num, dat_pos; prev = bit_pos = dat_pos = 0; - for (y = 0; y < (s->frame.linesize[0] * s->avctx->height); - y += s->frame.linesize[0]) { + for (y = 0; y < (frame->linesize[0] * s->avctx->height); + y += frame->linesize[0]) { for (x = y; x < y + s->avctx->width; x++) { node_num = s->num_huff_nodes[prev]; hnodes = s->huff_nodes[prev]; @@ -203,7 +200,7 @@ static void idcin_decode_vlcs(IdcinContext *s) bit_pos--; } - s->frame.data[0][x] = node_num; + frame->data[0][x] = node_num; prev = node_num; } } @@ -217,51 +214,38 @@ static int idcin_decode_frame(AVCodecContext *avctx, int buf_size = avpkt->size; IdcinContext *s = avctx->priv_data; const uint8_t *pal = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE, NULL); + AVFrame *frame = data; + int ret; s->buf = buf; s->size = buf_size; - if (s->frame.data[0]) - avctx->release_buffer(avctx, &s->frame); - - if (ff_get_buffer(avctx, &s->frame)) { + if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) { av_log(avctx, AV_LOG_ERROR, " id CIN Video: get_buffer() failed\n"); - return -1; + return ret; } - idcin_decode_vlcs(s); + idcin_decode_vlcs(s, frame); if (pal) { - s->frame.palette_has_changed = 1; + frame->palette_has_changed = 1; memcpy(s->pal, pal, AVPALETTE_SIZE); } /* make the palette available on the way out */ - memcpy(s->frame.data[1], s->pal, AVPALETTE_SIZE); + memcpy(frame->data[1], s->pal, AVPALETTE_SIZE); *got_frame = 1; - *(AVFrame*)data = s->frame; /* report that the buffer was completely consumed */ return buf_size; } -static av_cold int idcin_decode_end(AVCodecContext *avctx) -{ - IdcinContext *s = avctx->priv_data; - - if (s->frame.data[0]) - avctx->release_buffer(avctx, &s->frame); - - return 0; -} - AVCodec ff_idcin_decoder = { .name = "idcinvideo", .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_IDCIN, .priv_data_size = sizeof(IdcinContext), .init = idcin_decode_init, - .close = idcin_decode_end, .decode = idcin_decode_frame, .capabilities = CODEC_CAP_DR1, .long_name = NULL_IF_CONFIG_SMALL("id Quake II CIN video"), diff --git a/libavcodec/iff.c b/libavcodec/iff.c index 584e7f983f..08d548b0ea 100644 --- a/libavcodec/iff.c +++ b/libavcodec/iff.c @@ -168,8 +168,6 @@ static av_cold int decode_init(AVCodecContext *avctx) if (!s->planebuf) return AVERROR(ENOMEM); - s->frame.reference = 1; - return 0; } @@ -256,15 +254,11 @@ static int decode_frame_ilbm(AVCodecContext *avctx, const uint8_t *buf_end = buf+buf_size; int y, plane, res; - if (s->init) { - if ((res = avctx->reget_buffer(avctx, &s->frame)) < 0) { - av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); - return res; - } - } else if ((res = ff_get_buffer(avctx, &s->frame)) < 0) { - av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); + if ((res = ff_reget_buffer(avctx, &s->frame)) < 0) return res; - } else if (avctx->bits_per_coded_sample <= 8 && avctx->pix_fmt != AV_PIX_FMT_GRAY8) { + + if (!s->init && avctx->bits_per_coded_sample <= 8 && + avctx->pix_fmt != AV_PIX_FMT_GRAY8) { if ((res = cmap_read_palette(avctx, (uint32_t*)s->frame.data[1])) < 0) return res; } @@ -298,8 +292,11 @@ static int decode_frame_ilbm(AVCodecContext *avctx, } } + if ((res = av_frame_ref(data, &s->frame)) < 0) + return res; + *got_frame = 1; - *(AVFrame*)data = s->frame; + return buf_size; } @@ -313,15 +310,11 @@ static int decode_frame_byterun1(AVCodecContext *avctx, const uint8_t *buf_end = buf+buf_size; int y, plane, res; - if (s->init) { - if ((res = avctx->reget_buffer(avctx, &s->frame)) < 0) { - av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); - return res; - } - } else if ((res = ff_get_buffer(avctx, &s->frame)) < 0) { - av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); + if ((res = ff_reget_buffer(avctx, &s->frame)) < 0) return res; - } else if (avctx->bits_per_coded_sample <= 8 && avctx->pix_fmt != AV_PIX_FMT_GRAY8) { + + if (!s->init && avctx->bits_per_coded_sample <= 8 && + avctx->pix_fmt != AV_PIX_FMT_GRAY8) { if ((res = cmap_read_palette(avctx, (uint32_t*)s->frame.data[1])) < 0) return res; } @@ -354,16 +347,18 @@ static int decode_frame_byterun1(AVCodecContext *avctx, } } + if ((res = av_frame_ref(data, &s->frame)) < 0) + return res; + *got_frame = 1; - *(AVFrame*)data = s->frame; + return buf_size; } static av_cold int decode_end(AVCodecContext *avctx) { IffContext *s = avctx->priv_data; - if (s->frame.data[0]) - avctx->release_buffer(avctx, &s->frame); + av_frame_unref(&s->frame); av_freep(&s->planebuf); return 0; } diff --git a/libavcodec/imc.c b/libavcodec/imc.c index 9b984c12bb..06bff9bd41 100644 --- a/libavcodec/imc.c +++ b/libavcodec/imc.c @@ -940,7 +940,7 @@ static int imc_decode_frame(AVCodecContext *avctx, void *data, /* get output buffer */ frame->nb_samples = COEFFS; - if ((ret = ff_get_buffer(avctx, frame)) < 0) { + if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } diff --git a/libavcodec/indeo2.c b/libavcodec/indeo2.c index 1b4d51b6b1..37b3ea19cd 100644 --- a/libavcodec/indeo2.c +++ b/libavcodec/indeo2.c @@ -29,6 +29,7 @@ #include "avcodec.h" #include "get_bits.h" #include "indeo2data.h" +#include "internal.h" #include "mathops.h" typedef struct Ir2Context{ @@ -148,12 +149,7 @@ static int ir2_decode_frame(AVCodecContext *avctx, AVFrame * const p = &s->picture; int start, ret; - if (p->data[0]) - avctx->release_buffer(avctx, p); - - p->reference = 1; - p->buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE; - if ((ret = avctx->reget_buffer(avctx, p)) < 0) { + if ((ret = ff_reget_buffer(avctx, p)) < 0) { av_log(s->avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); return ret; } @@ -206,7 +202,9 @@ static int ir2_decode_frame(AVCodecContext *avctx, return ret; } - *picture = s->picture; + if ((ret = av_frame_ref(picture, &s->picture)) < 0) + return ret; + *got_frame = 1; return buf_size; @@ -241,8 +239,7 @@ static av_cold int ir2_decode_end(AVCodecContext *avctx) Ir2Context * const ic = avctx->priv_data; AVFrame *pic = &ic->picture; - if (pic->data[0]) - avctx->release_buffer(avctx, pic); + av_frame_unref(pic); return 0; } diff --git a/libavcodec/indeo3.c b/libavcodec/indeo3.c index 22f5e7916b..e519361aa2 100644 --- a/libavcodec/indeo3.c +++ b/libavcodec/indeo3.c @@ -81,7 +81,6 @@ typedef struct Cell { typedef struct Indeo3DecodeContext { AVCodecContext *avctx; - AVFrame frame; DSPContext dsp; GetBitContext gb; @@ -1034,6 +1033,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, Indeo3DecodeContext *ctx = avctx->priv_data; const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; + AVFrame *frame = data; int res; res = decode_frame_headers(ctx, avctx, buf, buf_size); @@ -1070,27 +1070,22 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, if ((res = decode_plane(ctx, avctx, &ctx->planes[2], ctx->v_data_ptr, ctx->v_data_size, 10))) return res; - if (ctx->frame.data[0]) - avctx->release_buffer(avctx, &ctx->frame); - - ctx->frame.reference = 0; - if ((res = ff_get_buffer(avctx, &ctx->frame)) < 0) { + if ((res = ff_get_buffer(avctx, frame, 0)) < 0) { av_log(ctx->avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return res; } output_plane(&ctx->planes[0], ctx->buf_sel, - ctx->frame.data[0], ctx->frame.linesize[0], + frame->data[0], frame->linesize[0], avctx->height); output_plane(&ctx->planes[1], ctx->buf_sel, - ctx->frame.data[1], ctx->frame.linesize[1], + frame->data[1], frame->linesize[1], (avctx->height + 3) >> 2); output_plane(&ctx->planes[2], ctx->buf_sel, - ctx->frame.data[2], ctx->frame.linesize[2], + frame->data[2], frame->linesize[2], (avctx->height + 3) >> 2); *got_frame = 1; - *(AVFrame*)data = ctx->frame; return buf_size; } @@ -1098,13 +1093,8 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, static av_cold int decode_close(AVCodecContext *avctx) { - Indeo3DecodeContext *ctx = avctx->priv_data; - free_frame_buffers(avctx->priv_data); - if (ctx->frame.data[0]) - avctx->release_buffer(avctx, &ctx->frame); - return 0; } diff --git a/libavcodec/internal.h b/libavcodec/internal.h index 05efbfc15a..75bd4b9b1b 100644 --- a/libavcodec/internal.h +++ b/libavcodec/internal.h @@ -26,34 +26,33 @@ #include +#include "libavutil/buffer.h" #include "libavutil/mathematics.h" #include "libavutil/pixfmt.h" #include "avcodec.h" #define FF_SANE_NB_CHANNELS 128U -typedef struct InternalBuffer { - uint8_t *base[AV_NUM_DATA_POINTERS]; - uint8_t *data[AV_NUM_DATA_POINTERS]; - int linesize[AV_NUM_DATA_POINTERS]; - int width; - int height; - enum AVPixelFormat pix_fmt; -} InternalBuffer; +typedef struct FramePool { + /** + * Pools for each data plane. For audio all the planes have the same size, + * so only pools[0] is used. + */ + AVBufferPool *pools[4]; + + /* + * Pool parameters + */ + int format; + int width, height; + int stride_align[AV_NUM_DATA_POINTERS]; + int linesize[4]; + int planes; + int channels; + int samples; +} FramePool; typedef struct AVCodecInternal { - /** - * internal buffer count - * used by default get/release/reget_buffer(). - */ - int buffer_count; - - /** - * internal buffers - * used by default get/release/reget_buffer(). - */ - InternalBuffer *buffer; - /** * Whether the parent AVCodecContext is a copy of the context which had * init() called on it. @@ -62,6 +61,21 @@ typedef struct AVCodecInternal { */ int is_copy; + /** + * Whether to allocate progress for frame threading. + * + * The codec must set it to 1 if it uses ff_thread_await/report_progress(), + * then progress will be allocated in ff_thread_get_buffer(). The frames + * then MUST be freed with ff_thread_release_buffer(). + * + * If the codec does not need to call the progress functions (there are no + * dependencies between the frames), it should leave this at 0. Then it can + * decode straight to the user-provided frames (which the user will then + * free with av_frame_unref()), there is no need to call + * ff_thread_release_buffer(). + */ + int allocate_progress; + #if FF_API_OLD_ENCODE_AUDIO /** * Internal sample count used by avcodec_encode_audio() to fabricate pts. @@ -76,11 +90,9 @@ typedef struct AVCodecInternal { */ int last_audio_frame; - /** - * The data for the last allocated audio frame. - * Stored here so we can free it. - */ - uint8_t *audio_data; + AVFrame to_free; + + FramePool *pool; } AVCodecInternal; struct AVCodecDefault { @@ -149,6 +161,12 @@ static av_always_inline int64_t ff_samples_to_time_base(AVCodecContext *avctx, * AVCodecContext.get_buffer() and should be used instead calling get_buffer() * directly. */ -int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame); +int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags); + +/** + * Identical in function to av_frame_make_writable(), except it uses + * ff_get_buffer() to allocate the buffer when needed. + */ +int ff_reget_buffer(AVCodecContext *avctx, AVFrame *frame); #endif /* AVCODEC_INTERNAL_H */ diff --git a/libavcodec/interplayvideo.c b/libavcodec/interplayvideo.c index 76e7d0fe41..57035fd11a 100644 --- a/libavcodec/interplayvideo.c +++ b/libavcodec/interplayvideo.c @@ -51,9 +51,8 @@ typedef struct IpvideoContext { AVCodecContext *avctx; DSPContext dsp; - AVFrame second_last_frame; - AVFrame last_frame; - AVFrame current_frame; + AVFrame *second_last_frame; + AVFrame *last_frame; const unsigned char *decoding_map; int decoding_map_size; @@ -67,10 +66,10 @@ typedef struct IpvideoContext { uint32_t pal[256]; } IpvideoContext; -static int copy_from(IpvideoContext *s, AVFrame *src, int delta_x, int delta_y) +static int copy_from(IpvideoContext *s, AVFrame *src, AVFrame *dst, int delta_x, int delta_y) { - int current_offset = s->pixel_ptr - s->current_frame.data[0]; - int motion_offset = current_offset + delta_y * s->current_frame.linesize[0] + int current_offset = s->pixel_ptr - dst->data[0]; + int motion_offset = current_offset + delta_y * dst->linesize[0] + delta_x * (1 + s->is_16bpp); if (motion_offset < 0) { av_log(s->avctx, AV_LOG_ERROR, " Interplay video: motion offset < 0 (%d)\n", motion_offset); @@ -85,21 +84,21 @@ static int copy_from(IpvideoContext *s, AVFrame *src, int delta_x, int delta_y) return AVERROR(EINVAL); } s->dsp.put_pixels_tab[!s->is_16bpp][0](s->pixel_ptr, src->data[0] + motion_offset, - s->current_frame.linesize[0], 8); + dst->linesize[0], 8); return 0; } -static int ipvideo_decode_block_opcode_0x0(IpvideoContext *s) +static int ipvideo_decode_block_opcode_0x0(IpvideoContext *s, AVFrame *frame) { - return copy_from(s, &s->last_frame, 0, 0); + return copy_from(s, s->last_frame, frame, 0, 0); } -static int ipvideo_decode_block_opcode_0x1(IpvideoContext *s) +static int ipvideo_decode_block_opcode_0x1(IpvideoContext *s, AVFrame *frame) { - return copy_from(s, &s->second_last_frame, 0, 0); + return copy_from(s, s->second_last_frame, frame, 0, 0); } -static int ipvideo_decode_block_opcode_0x2(IpvideoContext *s) +static int ipvideo_decode_block_opcode_0x2(IpvideoContext *s, AVFrame *frame) { unsigned char B; int x, y; @@ -120,10 +119,10 @@ static int ipvideo_decode_block_opcode_0x2(IpvideoContext *s) } av_dlog(NULL, " motion byte = %d, (x, y) = (%d, %d)\n", B, x, y); - return copy_from(s, &s->second_last_frame, x, y); + return copy_from(s, s->second_last_frame, frame, x, y); } -static int ipvideo_decode_block_opcode_0x3(IpvideoContext *s) +static int ipvideo_decode_block_opcode_0x3(IpvideoContext *s, AVFrame *frame) { unsigned char B; int x, y; @@ -146,10 +145,10 @@ static int ipvideo_decode_block_opcode_0x3(IpvideoContext *s) } av_dlog(NULL, " motion byte = %d, (x, y) = (%d, %d)\n", B, x, y); - return copy_from(s, &s->current_frame, x, y); + return copy_from(s, frame, frame, x, y); } -static int ipvideo_decode_block_opcode_0x4(IpvideoContext *s) +static int ipvideo_decode_block_opcode_0x4(IpvideoContext *s, AVFrame *frame) { int x, y; unsigned char B, BL, BH; @@ -167,10 +166,10 @@ static int ipvideo_decode_block_opcode_0x4(IpvideoContext *s) y = -8 + BH; av_dlog(NULL, " motion byte = %d, (x, y) = (%d, %d)\n", B, x, y); - return copy_from(s, &s->last_frame, x, y); + return copy_from(s, s->last_frame, frame, x, y); } -static int ipvideo_decode_block_opcode_0x5(IpvideoContext *s) +static int ipvideo_decode_block_opcode_0x5(IpvideoContext *s, AVFrame *frame) { signed char x, y; @@ -180,10 +179,10 @@ static int ipvideo_decode_block_opcode_0x5(IpvideoContext *s) y = bytestream2_get_byte(&s->stream_ptr); av_dlog(NULL, " motion bytes = %d, %d\n", x, y); - return copy_from(s, &s->last_frame, x, y); + return copy_from(s, s->last_frame, frame, x, y); } -static int ipvideo_decode_block_opcode_0x6(IpvideoContext *s) +static int ipvideo_decode_block_opcode_0x6(IpvideoContext *s, AVFrame *frame) { /* mystery opcode? skip multiple blocks? */ av_log(s->avctx, AV_LOG_ERROR, " Interplay video: Help! Mystery opcode 0x6 seen\n"); @@ -192,7 +191,7 @@ static int ipvideo_decode_block_opcode_0x6(IpvideoContext *s) return 0; } -static int ipvideo_decode_block_opcode_0x7(IpvideoContext *s) +static int ipvideo_decode_block_opcode_0x7(IpvideoContext *s, AVFrame *frame) { int x, y; unsigned char P[2]; @@ -231,7 +230,7 @@ static int ipvideo_decode_block_opcode_0x7(IpvideoContext *s) return 0; } -static int ipvideo_decode_block_opcode_0x8(IpvideoContext *s) +static int ipvideo_decode_block_opcode_0x8(IpvideoContext *s, AVFrame *frame) { int x, y; unsigned char P[4]; @@ -304,7 +303,7 @@ static int ipvideo_decode_block_opcode_0x8(IpvideoContext *s) return 0; } -static int ipvideo_decode_block_opcode_0x9(IpvideoContext *s) +static int ipvideo_decode_block_opcode_0x9(IpvideoContext *s, AVFrame *frame) { int x, y; unsigned char P[4]; @@ -369,7 +368,7 @@ static int ipvideo_decode_block_opcode_0x9(IpvideoContext *s) return 0; } -static int ipvideo_decode_block_opcode_0xA(IpvideoContext *s) +static int ipvideo_decode_block_opcode_0xA(IpvideoContext *s, AVFrame *frame) { int x, y; unsigned char P[8]; @@ -430,7 +429,7 @@ static int ipvideo_decode_block_opcode_0xA(IpvideoContext *s) return 0; } -static int ipvideo_decode_block_opcode_0xB(IpvideoContext *s) +static int ipvideo_decode_block_opcode_0xB(IpvideoContext *s, AVFrame *frame) { int y; @@ -444,7 +443,7 @@ static int ipvideo_decode_block_opcode_0xB(IpvideoContext *s) return 0; } -static int ipvideo_decode_block_opcode_0xC(IpvideoContext *s) +static int ipvideo_decode_block_opcode_0xC(IpvideoContext *s, AVFrame *frame) { int x, y; @@ -463,7 +462,7 @@ static int ipvideo_decode_block_opcode_0xC(IpvideoContext *s) return 0; } -static int ipvideo_decode_block_opcode_0xD(IpvideoContext *s) +static int ipvideo_decode_block_opcode_0xD(IpvideoContext *s, AVFrame *frame) { int y; unsigned char P[2]; @@ -483,7 +482,7 @@ static int ipvideo_decode_block_opcode_0xD(IpvideoContext *s) return 0; } -static int ipvideo_decode_block_opcode_0xE(IpvideoContext *s) +static int ipvideo_decode_block_opcode_0xE(IpvideoContext *s, AVFrame *frame) { int y; unsigned char pix; @@ -500,7 +499,7 @@ static int ipvideo_decode_block_opcode_0xE(IpvideoContext *s) return 0; } -static int ipvideo_decode_block_opcode_0xF(IpvideoContext *s) +static int ipvideo_decode_block_opcode_0xF(IpvideoContext *s, AVFrame *frame) { int x, y; unsigned char sample[2]; @@ -521,7 +520,7 @@ static int ipvideo_decode_block_opcode_0xF(IpvideoContext *s) return 0; } -static int ipvideo_decode_block_opcode_0x6_16(IpvideoContext *s) +static int ipvideo_decode_block_opcode_0x6_16(IpvideoContext *s, AVFrame *frame) { signed char x, y; @@ -530,10 +529,10 @@ static int ipvideo_decode_block_opcode_0x6_16(IpvideoContext *s) y = bytestream2_get_byte(&s->stream_ptr); av_dlog(NULL, " motion bytes = %d, %d\n", x, y); - return copy_from(s, &s->second_last_frame, x, y); + return copy_from(s, s->second_last_frame, frame, x, y); } -static int ipvideo_decode_block_opcode_0x7_16(IpvideoContext *s) +static int ipvideo_decode_block_opcode_0x7_16(IpvideoContext *s, AVFrame *frame) { int x, y; uint16_t P[2]; @@ -570,7 +569,7 @@ static int ipvideo_decode_block_opcode_0x7_16(IpvideoContext *s) return 0; } -static int ipvideo_decode_block_opcode_0x8_16(IpvideoContext *s) +static int ipvideo_decode_block_opcode_0x8_16(IpvideoContext *s, AVFrame *frame) { int x, y; uint16_t P[4]; @@ -646,7 +645,7 @@ static int ipvideo_decode_block_opcode_0x8_16(IpvideoContext *s) return 0; } -static int ipvideo_decode_block_opcode_0x9_16(IpvideoContext *s) +static int ipvideo_decode_block_opcode_0x9_16(IpvideoContext *s, AVFrame *frame) { int x, y; uint16_t P[4]; @@ -713,7 +712,7 @@ static int ipvideo_decode_block_opcode_0x9_16(IpvideoContext *s) return 0; } -static int ipvideo_decode_block_opcode_0xA_16(IpvideoContext *s) +static int ipvideo_decode_block_opcode_0xA_16(IpvideoContext *s, AVFrame *frame) { int x, y; uint16_t P[8]; @@ -779,7 +778,7 @@ static int ipvideo_decode_block_opcode_0xA_16(IpvideoContext *s) return 0; } -static int ipvideo_decode_block_opcode_0xB_16(IpvideoContext *s) +static int ipvideo_decode_block_opcode_0xB_16(IpvideoContext *s, AVFrame *frame) { int x, y; uint16_t *pixel_ptr = (uint16_t*)s->pixel_ptr; @@ -795,7 +794,7 @@ static int ipvideo_decode_block_opcode_0xB_16(IpvideoContext *s) return 0; } -static int ipvideo_decode_block_opcode_0xC_16(IpvideoContext *s) +static int ipvideo_decode_block_opcode_0xC_16(IpvideoContext *s, AVFrame *frame) { int x, y; uint16_t *pixel_ptr = (uint16_t*)s->pixel_ptr; @@ -815,7 +814,7 @@ static int ipvideo_decode_block_opcode_0xC_16(IpvideoContext *s) return 0; } -static int ipvideo_decode_block_opcode_0xD_16(IpvideoContext *s) +static int ipvideo_decode_block_opcode_0xD_16(IpvideoContext *s, AVFrame *frame) { int x, y; uint16_t P[2]; @@ -836,7 +835,7 @@ static int ipvideo_decode_block_opcode_0xD_16(IpvideoContext *s) return 0; } -static int ipvideo_decode_block_opcode_0xE_16(IpvideoContext *s) +static int ipvideo_decode_block_opcode_0xE_16(IpvideoContext *s, AVFrame *frame) { int x, y; uint16_t pix; @@ -855,7 +854,7 @@ static int ipvideo_decode_block_opcode_0xE_16(IpvideoContext *s) return 0; } -static int (* const ipvideo_decode_block[])(IpvideoContext *s) = { +static int (* const ipvideo_decode_block[])(IpvideoContext *s, AVFrame *frame) = { ipvideo_decode_block_opcode_0x0, ipvideo_decode_block_opcode_0x1, ipvideo_decode_block_opcode_0x2, ipvideo_decode_block_opcode_0x3, ipvideo_decode_block_opcode_0x4, ipvideo_decode_block_opcode_0x5, @@ -866,7 +865,7 @@ static int (* const ipvideo_decode_block[])(IpvideoContext *s) = { ipvideo_decode_block_opcode_0xE, ipvideo_decode_block_opcode_0xF, }; -static int (* const ipvideo_decode_block16[])(IpvideoContext *s) = { +static int (* const ipvideo_decode_block16[])(IpvideoContext *s, AVFrame *frame) = { ipvideo_decode_block_opcode_0x0, ipvideo_decode_block_opcode_0x1, ipvideo_decode_block_opcode_0x2, ipvideo_decode_block_opcode_0x3, ipvideo_decode_block_opcode_0x4, ipvideo_decode_block_opcode_0x5, @@ -877,7 +876,7 @@ static int (* const ipvideo_decode_block16[])(IpvideoContext *s) = { ipvideo_decode_block_opcode_0xE_16, ipvideo_decode_block_opcode_0x1, }; -static void ipvideo_decode_opcodes(IpvideoContext *s) +static void ipvideo_decode_opcodes(IpvideoContext *s, AVFrame *frame) { int x, y; unsigned char opcode; @@ -887,16 +886,16 @@ static void ipvideo_decode_opcodes(IpvideoContext *s) bytestream2_skip(&s->stream_ptr, 14); /* data starts 14 bytes in */ if (!s->is_16bpp) { /* this is PAL8, so make the palette available */ - memcpy(s->current_frame.data[1], s->pal, AVPALETTE_SIZE); + memcpy(frame->data[1], s->pal, AVPALETTE_SIZE); - s->stride = s->current_frame.linesize[0]; + s->stride = frame->linesize[0]; } else { - s->stride = s->current_frame.linesize[0] >> 1; + s->stride = frame->linesize[0] >> 1; s->mv_ptr = s->stream_ptr; bytestream2_skip(&s->mv_ptr, bytestream2_get_le16(&s->stream_ptr)); } s->line_inc = s->stride - 8; - s->upper_motion_limit_offset = (s->avctx->height - 8) * s->current_frame.linesize[0] + s->upper_motion_limit_offset = (s->avctx->height - 8) * frame->linesize[0] + (s->avctx->width - 8) * (1 + s->is_16bpp); init_get_bits(&gb, s->decoding_map, s->decoding_map_size * 8); @@ -909,13 +908,13 @@ static void ipvideo_decode_opcodes(IpvideoContext *s) x, y, opcode, bytestream2_tell(&s->stream_ptr)); if (!s->is_16bpp) { - s->pixel_ptr = s->current_frame.data[0] + x - + y*s->current_frame.linesize[0]; - ret = ipvideo_decode_block[opcode](s); + s->pixel_ptr = frame->data[0] + x + + y*frame->linesize[0]; + ret = ipvideo_decode_block[opcode](s, frame); } else { - s->pixel_ptr = s->current_frame.data[0] + x*2 - + y*s->current_frame.linesize[0]; - ret = ipvideo_decode_block16[opcode](s); + s->pixel_ptr = frame->data[0] + x*2 + + y*frame->linesize[0]; + ret = ipvideo_decode_block16[opcode](s, frame); } if (ret != 0) { av_log(s->avctx, AV_LOG_ERROR, " Interplay video: decode problem on frame %d, @ block (%d, %d)\n", @@ -942,8 +941,13 @@ static av_cold int ipvideo_decode_init(AVCodecContext *avctx) ff_dsputil_init(&s->dsp, avctx); - s->current_frame.data[0] = s->last_frame.data[0] = - s->second_last_frame.data[0] = NULL; + s->last_frame = av_frame_alloc(); + s->second_last_frame = av_frame_alloc(); + if (!s->last_frame || !s->second_last_frame) { + av_frame_free(&s->last_frame); + av_frame_free(&s->second_last_frame); + return AVERROR(ENOMEM); + } return 0; } @@ -955,6 +959,7 @@ static int ipvideo_decode_frame(AVCodecContext *avctx, const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; IpvideoContext *s = avctx->priv_data; + AVFrame *frame = data; int ret; /* decoding map contains 4 bits of information per 8x8 block */ @@ -969,8 +974,7 @@ static int ipvideo_decode_frame(AVCodecContext *avctx, bytestream2_init(&s->stream_ptr, buf + s->decoding_map_size, buf_size - s->decoding_map_size); - s->current_frame.reference = 3; - if ((ret = ff_get_buffer(avctx, &s->current_frame)) < 0) { + if ((ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF)) < 0) { av_log(avctx, AV_LOG_ERROR, " Interplay Video: get_buffer() failed\n"); return ret; } @@ -978,22 +982,20 @@ static int ipvideo_decode_frame(AVCodecContext *avctx, if (!s->is_16bpp) { const uint8_t *pal = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE, NULL); if (pal) { - s->current_frame.palette_has_changed = 1; + frame->palette_has_changed = 1; memcpy(s->pal, pal, AVPALETTE_SIZE); } } - ipvideo_decode_opcodes(s); + ipvideo_decode_opcodes(s, frame); *got_frame = 1; - *(AVFrame*)data = s->current_frame; /* shuffle frames */ - if (s->second_last_frame.data[0]) - avctx->release_buffer(avctx, &s->second_last_frame); - s->second_last_frame = s->last_frame; - s->last_frame = s->current_frame; - s->current_frame.data[0] = NULL; /* catch any access attempts */ + av_frame_unref(s->second_last_frame); + FFSWAP(AVFrame*, s->second_last_frame, s->last_frame); + if ((ret = av_frame_ref(s->last_frame, frame)) < 0) + return ret; /* report that the buffer was completely consumed */ return buf_size; @@ -1003,11 +1005,8 @@ static av_cold int ipvideo_decode_end(AVCodecContext *avctx) { IpvideoContext *s = avctx->priv_data; - /* release the last frame */ - if (s->last_frame.data[0]) - avctx->release_buffer(avctx, &s->last_frame); - if (s->second_last_frame.data[0]) - avctx->release_buffer(avctx, &s->second_last_frame); + av_frame_free(&s->last_frame); + av_frame_free(&s->second_last_frame); return 0; } diff --git a/libavcodec/intrax8.c b/libavcodec/intrax8.c index f4a2fc67c3..b81a9ca9c4 100644 --- a/libavcodec/intrax8.c +++ b/libavcodec/intrax8.c @@ -774,7 +774,7 @@ int ff_intrax8_decode_picture(IntraX8Context * const w, int dquant, int quant_of /*emulate MB info in the relevant tables*/ s->mbskip_table [mb_xy]=0; s->mbintra_table[mb_xy]=1; - s->current_picture.f.qscale_table[mb_xy] = w->quant; + s->current_picture.qscale_table[mb_xy] = w->quant; mb_xy++; } s->dest[0]+= 8; diff --git a/libavcodec/ituh263dec.c b/libavcodec/ituh263dec.c index 7f79982c6b..9a42c2d767 100644 --- a/libavcodec/ituh263dec.c +++ b/libavcodec/ituh263dec.c @@ -352,20 +352,20 @@ static void preview_obmc(MpegEncContext *s){ do{ if (get_bits1(&s->gb)) { /* skip mb */ - mot_val = s->current_picture.f.motion_val[0][s->block_index[0]]; + mot_val = s->current_picture.motion_val[0][s->block_index[0]]; mot_val[0 ]= mot_val[2 ]= mot_val[0+stride]= mot_val[2+stride]= 0; mot_val[1 ]= mot_val[3 ]= mot_val[1+stride]= mot_val[3+stride]= 0; - s->current_picture.f.mb_type[xy] = MB_TYPE_SKIP | MB_TYPE_16x16 | MB_TYPE_L0; + s->current_picture.mb_type[xy] = MB_TYPE_SKIP | MB_TYPE_16x16 | MB_TYPE_L0; goto end; } cbpc = get_vlc2(&s->gb, ff_h263_inter_MCBPC_vlc.table, INTER_MCBPC_VLC_BITS, 2); }while(cbpc == 20); if(cbpc & 4){ - s->current_picture.f.mb_type[xy] = MB_TYPE_INTRA; + s->current_picture.mb_type[xy] = MB_TYPE_INTRA; }else{ get_vlc2(&s->gb, ff_h263_cbpy_vlc.table, CBPY_VLC_BITS, 1); if (cbpc & 8) { @@ -377,7 +377,7 @@ static void preview_obmc(MpegEncContext *s){ } if ((cbpc & 16) == 0) { - s->current_picture.f.mb_type[xy] = MB_TYPE_16x16 | MB_TYPE_L0; + s->current_picture.mb_type[xy] = MB_TYPE_16x16 | MB_TYPE_L0; /* 16x16 motion prediction */ mot_val= ff_h263_pred_motion(s, 0, 0, &pred_x, &pred_y); if (s->umvplus) @@ -395,7 +395,7 @@ static void preview_obmc(MpegEncContext *s){ mot_val[1 ]= mot_val[3 ]= mot_val[1+stride]= mot_val[3+stride]= my; } else { - s->current_picture.f.mb_type[xy] = MB_TYPE_8x8 | MB_TYPE_L0; + s->current_picture.mb_type[xy] = MB_TYPE_8x8 | MB_TYPE_L0; for(i=0;i<4;i++) { mot_val = ff_h263_pred_motion(s, i, 0, &pred_x, &pred_y); if (s->umvplus) @@ -617,7 +617,7 @@ int ff_h263_decode_mb(MpegEncContext *s, s->block_last_index[i] = -1; s->mv_dir = MV_DIR_FORWARD; s->mv_type = MV_TYPE_16X16; - s->current_picture.f.mb_type[xy] = MB_TYPE_SKIP | MB_TYPE_16x16 | MB_TYPE_L0; + s->current_picture.mb_type[xy] = MB_TYPE_SKIP | MB_TYPE_16x16 | MB_TYPE_L0; s->mv[0][0][0] = 0; s->mv[0][0][1] = 0; s->mb_skipped = !(s->obmc | s->loop_filter); @@ -650,7 +650,7 @@ int ff_h263_decode_mb(MpegEncContext *s, s->mv_dir = MV_DIR_FORWARD; if ((cbpc & 16) == 0) { - s->current_picture.f.mb_type[xy] = MB_TYPE_16x16 | MB_TYPE_L0; + s->current_picture.mb_type[xy] = MB_TYPE_16x16 | MB_TYPE_L0; /* 16x16 motion prediction */ s->mv_type = MV_TYPE_16X16; ff_h263_pred_motion(s, 0, 0, &pred_x, &pred_y); @@ -675,7 +675,7 @@ int ff_h263_decode_mb(MpegEncContext *s, if (s->umvplus && (mx - pred_x) == 1 && (my - pred_y) == 1) skip_bits1(&s->gb); /* Bit stuffing to prevent PSC */ } else { - s->current_picture.f.mb_type[xy] = MB_TYPE_8x8 | MB_TYPE_L0; + s->current_picture.mb_type[xy] = MB_TYPE_8x8 | MB_TYPE_L0; s->mv_type = MV_TYPE_8X8; for(i=0;i<4;i++) { mot_val = ff_h263_pred_motion(s, i, 0, &pred_x, &pred_y); @@ -703,8 +703,8 @@ int ff_h263_decode_mb(MpegEncContext *s, } else if(s->pict_type==AV_PICTURE_TYPE_B) { int mb_type; const int stride= s->b8_stride; - int16_t *mot_val0 = s->current_picture.f.motion_val[0][2 * (s->mb_x + s->mb_y * stride)]; - int16_t *mot_val1 = s->current_picture.f.motion_val[1][2 * (s->mb_x + s->mb_y * stride)]; + int16_t *mot_val0 = s->current_picture.motion_val[0][2 * (s->mb_x + s->mb_y * stride)]; + int16_t *mot_val1 = s->current_picture.motion_val[1][2 * (s->mb_x + s->mb_y * stride)]; // const int mv_xy= s->mb_x + 1 + s->mb_y * s->mb_stride; //FIXME ugly @@ -787,7 +787,7 @@ int ff_h263_decode_mb(MpegEncContext *s, } } - s->current_picture.f.mb_type[xy] = mb_type; + s->current_picture.mb_type[xy] = mb_type; } else { /* I-Frame */ do{ cbpc = get_vlc2(&s->gb, ff_h263_intra_MCBPC_vlc.table, INTRA_MCBPC_VLC_BITS, 2); @@ -802,11 +802,11 @@ int ff_h263_decode_mb(MpegEncContext *s, dquant = cbpc & 4; s->mb_intra = 1; intra: - s->current_picture.f.mb_type[xy] = MB_TYPE_INTRA; + s->current_picture.mb_type[xy] = MB_TYPE_INTRA; if (s->h263_aic) { s->ac_pred = get_bits1(&s->gb); if(s->ac_pred){ - s->current_picture.f.mb_type[xy] = MB_TYPE_INTRA | MB_TYPE_ACPRED; + s->current_picture.mb_type[xy] = MB_TYPE_INTRA | MB_TYPE_ACPRED; s->h263_aic_dir = get_bits1(&s->gb); } diff --git a/libavcodec/ituh263enc.c b/libavcodec/ituh263enc.c index 05f9631d53..eb91142bd5 100644 --- a/libavcodec/ituh263enc.c +++ b/libavcodec/ituh263enc.c @@ -274,7 +274,7 @@ void ff_h263_encode_gob_header(MpegEncContext * s, int mb_line) */ void ff_clean_h263_qscales(MpegEncContext *s){ int i; - int8_t * const qscale_table = s->current_picture.f.qscale_table; + int8_t * const qscale_table = s->current_picture.qscale_table; ff_init_qscale_tab(s); @@ -528,8 +528,8 @@ void ff_h263_encode_mb(MpegEncContext * s, /* motion vectors: 8x8 mode*/ ff_h263_pred_motion(s, i, 0, &pred_x, &pred_y); - motion_x = s->current_picture.f.motion_val[0][s->block_index[i]][0]; - motion_y = s->current_picture.f.motion_val[0][s->block_index[i]][1]; + motion_x = s->current_picture.motion_val[0][s->block_index[i]][0]; + motion_y = s->current_picture.motion_val[0][s->block_index[i]][1]; if (!s->umvplus) { ff_h263_encode_motion_vector(s, motion_x - pred_x, motion_y - pred_y, 1); diff --git a/libavcodec/ivi_common.c b/libavcodec/ivi_common.c index 76782e5173..3d7cd13b7f 100644 --- a/libavcodec/ivi_common.c +++ b/libavcodec/ivi_common.c @@ -811,6 +811,7 @@ int ff_ivi_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, { IVI45DecContext *ctx = avctx->priv_data; const uint8_t *buf = avpkt->data; + AVFrame *frame = data; int buf_size = avpkt->size; int result, p, b; @@ -861,30 +862,25 @@ int ff_ivi_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, av_log(avctx, AV_LOG_ERROR, "Buffer contains IP frames!\n"); } - if (ctx->frame.data[0]) - avctx->release_buffer(avctx, &ctx->frame); - - ctx->frame.reference = 0; avcodec_set_dimensions(avctx, ctx->planes[0].width, ctx->planes[0].height); - if ((result = ff_get_buffer(avctx, &ctx->frame)) < 0) { + if ((result = ff_get_buffer(avctx, frame, 0)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return result; } if (ctx->is_scalable) { if (avctx->codec_id == AV_CODEC_ID_INDEO4) - ff_ivi_recompose_haar(&ctx->planes[0], ctx->frame.data[0], ctx->frame.linesize[0]); + ff_ivi_recompose_haar(&ctx->planes[0], frame->data[0], frame->linesize[0]); else - ff_ivi_recompose53 (&ctx->planes[0], ctx->frame.data[0], ctx->frame.linesize[0]); + ff_ivi_recompose53 (&ctx->planes[0], frame->data[0], frame->linesize[0]); } else { - ivi_output_plane(&ctx->planes[0], ctx->frame.data[0], ctx->frame.linesize[0]); + ivi_output_plane(&ctx->planes[0], frame->data[0], frame->linesize[0]); } - ivi_output_plane(&ctx->planes[2], ctx->frame.data[1], ctx->frame.linesize[1]); - ivi_output_plane(&ctx->planes[1], ctx->frame.data[2], ctx->frame.linesize[2]); + ivi_output_plane(&ctx->planes[2], frame->data[1], frame->linesize[1]); + ivi_output_plane(&ctx->planes[1], frame->data[2], frame->linesize[2]); *got_frame = 1; - *(AVFrame*)data = ctx->frame; return buf_size; } @@ -901,9 +897,6 @@ av_cold int ff_ivi_decode_close(AVCodecContext *avctx) if (ctx->mb_vlc.cust_tab.table) ff_free_vlc(&ctx->mb_vlc.cust_tab); - if (ctx->frame.data[0]) - avctx->release_buffer(avctx, &ctx->frame); - #if IVI4_STREAM_ANALYSER if (avctx->codec_id == AV_CODEC_ID_INDEO4) { if (ctx->is_scalable) diff --git a/libavcodec/ivi_common.h b/libavcodec/ivi_common.h index a3fb3140e2..aeb6b15877 100644 --- a/libavcodec/ivi_common.h +++ b/libavcodec/ivi_common.h @@ -195,7 +195,6 @@ typedef struct IVIPicConfig { typedef struct IVI45DecContext { GetBitContext gb; - AVFrame frame; RVMapDesc rvmap_tabs[9]; ///< local corrected copy of the static rvmap tables uint32_t frame_num; diff --git a/libavcodec/jvdec.c b/libavcodec/jvdec.c index 8c919d290e..6b82c6a45b 100644 --- a/libavcodec/jvdec.c +++ b/libavcodec/jvdec.c @@ -28,6 +28,7 @@ #include "avcodec.h" #include "dsputil.h" #include "get_bits.h" +#include "internal.h" #include "libavutil/intreadwrite.h" typedef struct JvContext { @@ -136,16 +137,16 @@ static int decode_frame(AVCodecContext *avctx, int buf_size = avpkt->size; const uint8_t *buf = avpkt->data; const uint8_t *buf_end = buf + buf_size; - int video_size, video_type, i, j; + int video_size, video_type, i, j, ret; video_size = AV_RL32(buf); video_type = buf[4]; buf += 5; if (video_size) { - if (avctx->reget_buffer(avctx, &s->frame) < 0) { + if ((ret = ff_reget_buffer(avctx, &s->frame)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); - return -1; + return ret; } if (video_type == 0 || video_type == 1) { @@ -185,8 +186,9 @@ static int decode_frame(AVCodecContext *avctx, s->palette_has_changed = 0; memcpy(s->frame.data[1], s->palette, AVPALETTE_SIZE); + if ((ret = av_frame_ref(data, &s->frame)) < 0) + return ret; *got_frame = 1; - *(AVFrame*)data = s->frame; } return buf_size; @@ -196,8 +198,7 @@ static av_cold int decode_close(AVCodecContext *avctx) { JvContext *s = avctx->priv_data; - if(s->frame.data[0]) - avctx->release_buffer(avctx, &s->frame); + av_frame_unref(&s->frame); return 0; } diff --git a/libavcodec/kgv1dec.c b/libavcodec/kgv1dec.c index 01655a54b8..74ae6b7ffe 100644 --- a/libavcodec/kgv1dec.c +++ b/libavcodec/kgv1dec.c @@ -32,20 +32,20 @@ typedef struct { AVCodecContext *avctx; - AVFrame prev, cur; + AVFrame prev; } KgvContext; static void decode_flush(AVCodecContext *avctx) { KgvContext * const c = avctx->priv_data; - if (c->prev.data[0]) - avctx->release_buffer(avctx, &c->prev); + av_frame_unref(&c->prev); } static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { + AVFrame *frame = data; const uint8_t *buf = avpkt->data; const uint8_t *buf_end = buf + avpkt->size; KgvContext * const c = avctx->priv_data; @@ -65,17 +65,15 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, return res; if (w != avctx->width || h != avctx->height) { - if (c->prev.data[0]) - avctx->release_buffer(avctx, &c->prev); + av_frame_unref(&c->prev); avcodec_set_dimensions(avctx, w, h); } maxcnt = w * h; - c->cur.reference = 3; - if ((res = ff_get_buffer(avctx, &c->cur)) < 0) + if ((res = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF)) < 0) return res; - out = (uint16_t *) c->cur.data[0]; + out = (uint16_t *) frame->data[0]; if (c->prev.data[0]) { prev = (uint16_t *) c->prev.data[0]; } else { @@ -156,12 +154,11 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, if (outcnt - maxcnt) av_log(avctx, AV_LOG_DEBUG, "frame finished with %d diff\n", outcnt - maxcnt); - *got_frame = 1; - *(AVFrame*)data = c->cur; + av_frame_unref(&c->prev); + if ((res = av_frame_ref(&c->prev, frame)) < 0) + return res; - if (c->prev.data[0]) - avctx->release_buffer(avctx, &c->prev); - FFSWAP(AVFrame, c->cur, c->prev); + *got_frame = 1; return avpkt->size; } diff --git a/libavcodec/kmvc.c b/libavcodec/kmvc.c index 3ed01ad0e1..574d053677 100644 --- a/libavcodec/kmvc.c +++ b/libavcodec/kmvc.c @@ -41,7 +41,6 @@ */ typedef struct KmvcContext { AVCodecContext *avctx; - AVFrame pic; int setpal; int palsize; @@ -247,6 +246,7 @@ static int decode_frame(AVCodecContext * avctx, void *data, int *got_frame, AVPacket *avpkt) { KmvcContext *const ctx = avctx->priv_data; + AVFrame *frame = data; uint8_t *out, *src; int i, ret; int header; @@ -254,12 +254,8 @@ static int decode_frame(AVCodecContext * avctx, void *data, int *got_frame, const uint8_t *pal = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE, NULL); bytestream2_init(&ctx->g, avpkt->data, avpkt->size); - if (ctx->pic.data[0]) - avctx->release_buffer(avctx, &ctx->pic); - ctx->pic.reference = 1; - ctx->pic.buffer_hints = FF_BUFFER_HINTS_VALID; - if ((ret = ff_get_buffer(avctx, &ctx->pic)) < 0) { + if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } @@ -277,15 +273,15 @@ static int decode_frame(AVCodecContext * avctx, void *data, int *got_frame, } if (header & KMVC_KEYFRAME) { - ctx->pic.key_frame = 1; - ctx->pic.pict_type = AV_PICTURE_TYPE_I; + frame->key_frame = 1; + frame->pict_type = AV_PICTURE_TYPE_I; } else { - ctx->pic.key_frame = 0; - ctx->pic.pict_type = AV_PICTURE_TYPE_P; + frame->key_frame = 0; + frame->pict_type = AV_PICTURE_TYPE_P; } if (header & KMVC_PALETTE) { - ctx->pic.palette_has_changed = 1; + frame->palette_has_changed = 1; // palette starts from index 1 and has 127 entries for (i = 1; i <= ctx->palsize; i++) { ctx->pal[i] = bytestream2_get_be24(&ctx->g); @@ -293,17 +289,17 @@ static int decode_frame(AVCodecContext * avctx, void *data, int *got_frame, } if (pal) { - ctx->pic.palette_has_changed = 1; + frame->palette_has_changed = 1; memcpy(ctx->pal, pal, AVPALETTE_SIZE); } if (ctx->setpal) { ctx->setpal = 0; - ctx->pic.palette_has_changed = 1; + frame->palette_has_changed = 1; } /* make the palette available on the way out */ - memcpy(ctx->pic.data[1], ctx->pal, 1024); + memcpy(frame->data[1], ctx->pal, 1024); blocksize = bytestream2_get_byte(&ctx->g); @@ -328,12 +324,12 @@ static int decode_frame(AVCodecContext * avctx, void *data, int *got_frame, return AVERROR_INVALIDDATA; } - out = ctx->pic.data[0]; + out = frame->data[0]; src = ctx->cur; for (i = 0; i < avctx->height; i++) { memcpy(out, src, avctx->width); src += 320; - out += ctx->pic.linesize[0]; + out += frame->linesize[0]; } /* flip buffers */ @@ -346,7 +342,6 @@ static int decode_frame(AVCodecContext * avctx, void *data, int *got_frame, } *got_frame = 1; - *(AVFrame *) data = ctx->pic; /* always report that the buffer was completely consumed */ return avpkt->size; @@ -415,8 +410,6 @@ static av_cold int decode_end(AVCodecContext * avctx) av_freep(&c->frm0); av_freep(&c->frm1); - if (c->pic.data[0]) - avctx->release_buffer(avctx, &c->pic); return 0; } diff --git a/libavcodec/lagarith.c b/libavcodec/lagarith.c index 33dd8b0c53..9d84d263c9 100644 --- a/libavcodec/lagarith.c +++ b/libavcodec/lagarith.c @@ -48,7 +48,6 @@ enum LagarithFrameType { typedef struct LagarithContext { AVCodecContext *avctx; - AVFrame picture; DSPContext dsp; int zeros; /**< number of consecutive zero bytes encountered */ int zeros_rem; /**< number of zero bytes remaining to output */ @@ -502,19 +501,14 @@ static int lag_decode_frame(AVCodecContext *avctx, const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; LagarithContext *l = avctx->priv_data; - AVFrame *const p = &l->picture; + ThreadFrame frame = { .f = data }; + AVFrame *const p = data; uint8_t frametype = 0; uint32_t offset_gu = 0, offset_bv = 0, offset_ry = 9; uint32_t offs[4]; uint8_t *srcs[4], *dst; int i, j, planes = 3; - AVFrame *picture = data; - - if (p->data[0]) - ff_thread_release_buffer(avctx, p); - - p->reference = 0; p->key_frame = 1; frametype = buf[0]; @@ -526,7 +520,7 @@ static int lag_decode_frame(AVCodecContext *avctx, case FRAME_SOLID_RGBA: avctx->pix_fmt = AV_PIX_FMT_RGB32; - if (ff_thread_get_buffer(avctx, p) < 0) { + if (ff_thread_get_buffer(avctx, &frame, 0) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return -1; } @@ -548,7 +542,7 @@ static int lag_decode_frame(AVCodecContext *avctx, if (frametype == FRAME_ARITH_RGB24 || frametype == FRAME_U_RGB24) avctx->pix_fmt = AV_PIX_FMT_RGB24; - if (ff_thread_get_buffer(avctx, p) < 0) { + if (ff_thread_get_buffer(avctx, &frame, 0) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return -1; } @@ -608,7 +602,7 @@ static int lag_decode_frame(AVCodecContext *avctx, case FRAME_ARITH_YUY2: avctx->pix_fmt = AV_PIX_FMT_YUV422P; - if (ff_thread_get_buffer(avctx, p) < 0) { + if (ff_thread_get_buffer(avctx, &frame, 0) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return -1; } @@ -634,7 +628,7 @@ static int lag_decode_frame(AVCodecContext *avctx, case FRAME_ARITH_YV12: avctx->pix_fmt = AV_PIX_FMT_YUV420P; - if (ff_thread_get_buffer(avctx, p) < 0) { + if (ff_thread_get_buffer(avctx, &frame, 0) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return -1; } @@ -663,7 +657,6 @@ static int lag_decode_frame(AVCodecContext *avctx, return -1; } - *picture = *p; *got_frame = 1; return buf_size; @@ -683,8 +676,6 @@ static av_cold int lag_decode_end(AVCodecContext *avctx) { LagarithContext *l = avctx->priv_data; - if (l->picture.data[0]) - ff_thread_release_buffer(avctx, &l->picture); av_freep(&l->rgb_planes); return 0; diff --git a/libavcodec/lcldec.c b/libavcodec/lcldec.c index 914d4b2775..957143dd75 100644 --- a/libavcodec/lcldec.c +++ b/libavcodec/lcldec.c @@ -55,8 +55,6 @@ * Decoder context */ typedef struct LclDecContext { - AVFrame pic; - // Image type int imgtype; // Compression type @@ -160,6 +158,7 @@ static int zlib_decomp(AVCodecContext *avctx, const uint8_t *src, int src_len, i */ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { + AVFrame *frame = data; const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; LclDecContext * const c = avctx->priv_data; @@ -176,17 +175,12 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac unsigned int mthread_inlen, mthread_outlen; unsigned int len = buf_size; - if(c->pic.data[0]) - avctx->release_buffer(avctx, &c->pic); - - c->pic.reference = 0; - c->pic.buffer_hints = FF_BUFFER_HINTS_VALID; - if ((ret = ff_get_buffer(avctx, &c->pic)) < 0) { + if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } - outptr = c->pic.data[0]; // Output image pointer + outptr = frame->data[0]; // Output image pointer /* Decompress frame */ switch (avctx->codec_id) { @@ -374,9 +368,9 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac } /* Convert colorspace */ - y_out = c->pic.data[0] + (height - 1) * c->pic.linesize[0]; - u_out = c->pic.data[1] + (height - 1) * c->pic.linesize[1]; - v_out = c->pic.data[2] + (height - 1) * c->pic.linesize[2]; + y_out = frame->data[0] + (height - 1) * frame->linesize[0]; + u_out = frame->data[1] + (height - 1) * frame->linesize[1]; + v_out = frame->data[2] + (height - 1) * frame->linesize[2]; switch (c->imgtype) { case IMGTYPE_YUV111: for (row = 0; row < height; row++) { @@ -385,9 +379,9 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac u_out[col] = *encoded++ + 128; v_out[col] = *encoded++ + 128; } - y_out -= c->pic.linesize[0]; - u_out -= c->pic.linesize[1]; - v_out -= c->pic.linesize[2]; + y_out -= frame->linesize[0]; + u_out -= frame->linesize[1]; + v_out -= frame->linesize[2]; } break; case IMGTYPE_YUV422: @@ -400,14 +394,14 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac v_out[ col >> 1 ] = *encoded++ + 128; v_out[(col >> 1) + 1] = *encoded++ + 128; } - y_out -= c->pic.linesize[0]; - u_out -= c->pic.linesize[1]; - v_out -= c->pic.linesize[2]; + y_out -= frame->linesize[0]; + u_out -= frame->linesize[1]; + v_out -= frame->linesize[2]; } break; case IMGTYPE_RGB24: for (row = height - 1; row >= 0; row--) { - pixel_ptr = row * c->pic.linesize[0]; + pixel_ptr = row * frame->linesize[0]; memcpy(outptr + pixel_ptr, encoded, 3 * width); encoded += 3 * width; } @@ -420,9 +414,9 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac u_out[col >> 2] = *encoded++ + 128; v_out[col >> 2] = *encoded++ + 128; } - y_out -= c->pic.linesize[0]; - u_out -= c->pic.linesize[1]; - v_out -= c->pic.linesize[2]; + y_out -= frame->linesize[0]; + u_out -= frame->linesize[1]; + v_out -= frame->linesize[2]; } break; case IMGTYPE_YUV211: @@ -433,26 +427,26 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac u_out[col >> 1] = *encoded++ + 128; v_out[col >> 1] = *encoded++ + 128; } - y_out -= c->pic.linesize[0]; - u_out -= c->pic.linesize[1]; - v_out -= c->pic.linesize[2]; + y_out -= frame->linesize[0]; + u_out -= frame->linesize[1]; + v_out -= frame->linesize[2]; } break; case IMGTYPE_YUV420: - u_out = c->pic.data[1] + ((height >> 1) - 1) * c->pic.linesize[1]; - v_out = c->pic.data[2] + ((height >> 1) - 1) * c->pic.linesize[2]; + u_out = frame->data[1] + ((height >> 1) - 1) * frame->linesize[1]; + v_out = frame->data[2] + ((height >> 1) - 1) * frame->linesize[2]; for (row = 0; row < height - 1; row += 2) { for (col = 0; col < width - 1; col += 2) { memcpy(y_out + col, encoded, 2); encoded += 2; - memcpy(y_out + col - c->pic.linesize[0], encoded, 2); + memcpy(y_out + col - frame->linesize[0], encoded, 2); encoded += 2; u_out[col >> 1] = *encoded++ + 128; v_out[col >> 1] = *encoded++ + 128; } - y_out -= c->pic.linesize[0] << 1; - u_out -= c->pic.linesize[1]; - v_out -= c->pic.linesize[2]; + y_out -= frame->linesize[0] << 1; + u_out -= frame->linesize[1]; + v_out -= frame->linesize[2]; } break; default: @@ -461,7 +455,6 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac } *got_frame = 1; - *(AVFrame*)data = c->pic; /* always report that the buffer was completely consumed */ return buf_size; @@ -625,8 +618,6 @@ static av_cold int decode_end(AVCodecContext *avctx) LclDecContext * const c = avctx->priv_data; av_freep(&c->decomp_buf); - if (c->pic.data[0]) - avctx->release_buffer(avctx, &c->pic); #if CONFIG_ZLIB_DECODER if (avctx->codec_id == AV_CODEC_ID_ZLIB) inflateEnd(&c->zstream); diff --git a/libavcodec/libgsm.c b/libavcodec/libgsm.c index baa65bea71..3159f286da 100644 --- a/libavcodec/libgsm.c +++ b/libavcodec/libgsm.c @@ -202,7 +202,7 @@ static int libgsm_decode_frame(AVCodecContext *avctx, void *data, /* get output buffer */ frame->nb_samples = avctx->frame_size; - if ((ret = ff_get_buffer(avctx, frame)) < 0) { + if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } diff --git a/libavcodec/libilbc.c b/libavcodec/libilbc.c index cabac053c2..d47227cada 100644 --- a/libavcodec/libilbc.c +++ b/libavcodec/libilbc.c @@ -90,7 +90,7 @@ static int ilbc_decode_frame(AVCodecContext *avctx, void *data, } frame->nb_samples = s->decoder.blockl; - if ((ret = ff_get_buffer(avctx, frame)) < 0) { + if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } diff --git a/libavcodec/libopencore-amr.c b/libavcodec/libopencore-amr.c index d3bd7431f5..23efa6ca0b 100644 --- a/libavcodec/libopencore-amr.c +++ b/libavcodec/libopencore-amr.c @@ -103,7 +103,7 @@ static int amr_nb_decode_frame(AVCodecContext *avctx, void *data, /* get output buffer */ frame->nb_samples = 160; - if ((ret = ff_get_buffer(avctx, frame)) < 0) { + if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } diff --git a/libavcodec/libopenjpegdec.c b/libavcodec/libopenjpegdec.c index 8f956f473f..19ab1605ec 100644 --- a/libavcodec/libopenjpegdec.c +++ b/libavcodec/libopenjpegdec.c @@ -67,7 +67,6 @@ static const enum AVPixelFormat any_pix_fmts[] = {RGB_PIXEL_FORMATS, typedef struct { AVClass *class; opj_dparameters_t dec_params; - AVFrame image; int lowres; int lowqual; } LibOpenJPEGContext; @@ -239,16 +238,6 @@ static av_cold int libopenjpeg_decode_init(AVCodecContext *avctx) LibOpenJPEGContext *ctx = avctx->priv_data; opj_set_default_decoder_parameters(&ctx->dec_params); - avcodec_get_frame_defaults(&ctx->image); - avctx->coded_frame = &ctx->image; - return 0; -} - -static av_cold int libopenjpeg_decode_init_thread_copy(AVCodecContext *avctx) -{ - LibOpenJPEGContext *ctx = avctx->priv_data; - - avctx->coded_frame = &ctx->image; return 0; } @@ -259,7 +248,8 @@ static int libopenjpeg_decode_frame(AVCodecContext *avctx, uint8_t *buf = avpkt->data; int buf_size = avpkt->size; LibOpenJPEGContext *ctx = avctx->priv_data; - AVFrame *picture = &ctx->image, *output = data; + ThreadFrame frame = { .f = data }; + AVFrame *picture = data; const AVPixFmtDescriptor *desc; opj_dinfo_t *dec; opj_cio_t *stream; @@ -347,10 +337,7 @@ static int libopenjpeg_decode_frame(AVCodecContext *avctx, if (image->comps[i].prec > avctx->bits_per_raw_sample) avctx->bits_per_raw_sample = image->comps[i].prec; - if (picture->data[0]) - ff_thread_release_buffer(avctx, picture); - - if (ff_thread_get_buffer(avctx, picture) < 0) { + if (ff_thread_get_buffer(avctx, &frame, 0) < 0) { av_log(avctx, AV_LOG_ERROR, "ff_thread_get_buffer() failed\n"); goto done; } @@ -411,7 +398,6 @@ static int libopenjpeg_decode_frame(AVCodecContext *avctx, goto done; } - *output = ctx->image; *got_frame = 1; ret = buf_size; @@ -421,15 +407,6 @@ done: return ret; } -static av_cold int libopenjpeg_decode_close(AVCodecContext *avctx) -{ - LibOpenJPEGContext *ctx = avctx->priv_data; - - if (ctx->image.data[0]) - ff_thread_release_buffer(avctx, &ctx->image); - return 0; -} - #define OFFSET(x) offsetof(LibOpenJPEGContext, x) #define VD AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM @@ -452,10 +429,8 @@ AVCodec ff_libopenjpeg_decoder = { .id = AV_CODEC_ID_JPEG2000, .priv_data_size = sizeof(LibOpenJPEGContext), .init = libopenjpeg_decode_init, - .close = libopenjpeg_decode_close, .decode = libopenjpeg_decode_frame, .capabilities = CODEC_CAP_DR1 | CODEC_CAP_FRAME_THREADS, .long_name = NULL_IF_CONFIG_SMALL("OpenJPEG JPEG 2000"), .priv_class = &class, - .init_thread_copy = ONLY_IF_THREADS_ENABLED(libopenjpeg_decode_init_thread_copy), }; diff --git a/libavcodec/libopusdec.c b/libavcodec/libopusdec.c index 0bf040b33b..8c33e91a74 100644 --- a/libavcodec/libopusdec.c +++ b/libavcodec/libopusdec.c @@ -116,7 +116,7 @@ static int libopus_decode(AVCodecContext *avc, void *data, int ret, nb_samples; frame->nb_samples = MAX_FRAME_SIZE; - ret = ff_get_buffer(avc, frame); + ret = ff_get_buffer(avc, frame, 0); if (ret < 0) { av_log(avc, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; diff --git a/libavcodec/libschroedingerdec.c b/libavcodec/libschroedingerdec.c index d0077d8a01..7fedc63221 100644 --- a/libavcodec/libschroedingerdec.c +++ b/libavcodec/libschroedingerdec.c @@ -70,9 +70,6 @@ typedef struct SchroDecoderParams { /** end of sequence pulled */ int eos_pulled; - - /** decoded picture */ - AVFrame dec_frame; } SchroDecoderParams; typedef struct SchroParseUnitContext { @@ -219,6 +216,7 @@ static int libschroedinger_decode_frame(AVCodecContext *avctx, SchroDecoder *decoder = p_schro_params->decoder; SchroBuffer *enc_buf; SchroFrame* frame; + AVFrame *avframe = data; int state; int go = 1; int outer = 1; @@ -312,35 +310,29 @@ static int libschroedinger_decode_frame(AVCodecContext *avctx, framewithpts = ff_schro_queue_pop(&p_schro_params->dec_frame_queue); if (framewithpts && framewithpts->frame) { - if (p_schro_params->dec_frame.data[0]) - avctx->release_buffer(avctx, &p_schro_params->dec_frame); - if (ff_get_buffer(avctx, &p_schro_params->dec_frame) < 0) { + if (ff_get_buffer(avctx, avframe, 0) < 0) { av_log(avctx, AV_LOG_ERROR, "Unable to allocate buffer\n"); return AVERROR(ENOMEM); } - memcpy(p_schro_params->dec_frame.data[0], + memcpy(avframe->data[0], framewithpts->frame->components[0].data, framewithpts->frame->components[0].length); - memcpy(p_schro_params->dec_frame.data[1], + memcpy(avframe->data[1], framewithpts->frame->components[1].data, framewithpts->frame->components[1].length); - memcpy(p_schro_params->dec_frame.data[2], + memcpy(avframe->data[2], framewithpts->frame->components[2].data, framewithpts->frame->components[2].length); /* Fill frame with current buffer data from Schroedinger. */ - p_schro_params->dec_frame.format = -1; /* Unknown -1 */ - p_schro_params->dec_frame.width = framewithpts->frame->width; - p_schro_params->dec_frame.height = framewithpts->frame->height; - p_schro_params->dec_frame.pkt_pts = framewithpts->pts; - p_schro_params->dec_frame.linesize[0] = framewithpts->frame->components[0].stride; - p_schro_params->dec_frame.linesize[1] = framewithpts->frame->components[1].stride; - p_schro_params->dec_frame.linesize[2] = framewithpts->frame->components[2].stride; + avframe->pkt_pts = framewithpts->pts; + avframe->linesize[0] = framewithpts->frame->components[0].stride; + avframe->linesize[1] = framewithpts->frame->components[1].stride; + avframe->linesize[2] = framewithpts->frame->components[2].stride; - *(AVFrame*)data = p_schro_params->dec_frame; *got_frame = 1; /* Now free the frame resources. */ @@ -361,9 +353,6 @@ static av_cold int libschroedinger_decode_close(AVCodecContext *avctx) schro_decoder_free(p_schro_params->decoder); av_freep(&p_schro_params->format); - if (p_schro_params->dec_frame.data[0]) - avctx->release_buffer(avctx, &p_schro_params->dec_frame); - /* Free data in the output frame queue. */ ff_schro_queue_free(&p_schro_params->dec_frame_queue, libschroedinger_decode_frame_free); diff --git a/libavcodec/libspeexdec.c b/libavcodec/libspeexdec.c index 549ff1dfee..5b656963c1 100644 --- a/libavcodec/libspeexdec.c +++ b/libavcodec/libspeexdec.c @@ -116,7 +116,7 @@ static int libspeex_decode_frame(AVCodecContext *avctx, void *data, /* get output buffer */ frame->nb_samples = s->frame_size; - if ((ret = ff_get_buffer(avctx, frame)) < 0) { + if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } diff --git a/libavcodec/libvpxdec.c b/libavcodec/libvpxdec.c index 54eee31dcf..237b0f6a53 100644 --- a/libavcodec/libvpxdec.c +++ b/libavcodec/libvpxdec.c @@ -30,6 +30,7 @@ #include "libavutil/common.h" #include "libavutil/imgutils.h" #include "avcodec.h" +#include "internal.h" typedef struct VP8DecoderContext { struct vpx_codec_ctx decoder; @@ -65,6 +66,7 @@ static int vp8_decode(AVCodecContext *avctx, AVFrame *picture = data; const void *iter = NULL; struct vpx_image *img; + int ret; if (vpx_codec_decode(&ctx->decoder, avpkt->data, avpkt->size, NULL, 0) != VPX_CODEC_OK) { @@ -92,14 +94,10 @@ static int vp8_decode(AVCodecContext *avctx, return AVERROR_INVALIDDATA; avcodec_set_dimensions(avctx, img->d_w, img->d_h); } - picture->data[0] = img->planes[0]; - picture->data[1] = img->planes[1]; - picture->data[2] = img->planes[2]; - picture->data[3] = NULL; - picture->linesize[0] = img->stride[0]; - picture->linesize[1] = img->stride[1]; - picture->linesize[2] = img->stride[2]; - picture->linesize[3] = 0; + if ((ret = ff_get_buffer(avctx, picture, 0)) < 0) + return ret; + av_image_copy(picture->data, picture->linesize, img->planes, + img->stride, avctx->pix_fmt, img->d_w, img->d_h); *got_frame = 1; } return avpkt->size; @@ -126,7 +124,7 @@ AVCodec ff_libvpx_vp8_decoder = { .init = vp8_init, .close = vp8_free, .decode = vp8_decode, - .capabilities = CODEC_CAP_AUTO_THREADS, + .capabilities = CODEC_CAP_AUTO_THREADS | CODEC_CAP_DR1, .long_name = NULL_IF_CONFIG_SMALL("libvpx VP8"), }; #endif /* CONFIG_LIBVPX_VP8_DECODER */ diff --git a/libavcodec/ljpegenc.c b/libavcodec/ljpegenc.c index 555bffa4ee..c7291ada67 100644 --- a/libavcodec/ljpegenc.c +++ b/libavcodec/ljpegenc.c @@ -63,7 +63,10 @@ static int encode_picture_lossless(AVCodecContext *avctx, AVPacket *pkt, init_put_bits(&s->pb, pkt->data, pkt->size); - *p = *pict; + av_frame_unref(p); + ret = av_frame_ref(p, pict); + if (ret < 0) + return ret; p->pict_type= AV_PICTURE_TYPE_I; p->key_frame= 1; diff --git a/libavcodec/loco.c b/libavcodec/loco.c index b1ad41ae46..427a56f0fa 100644 --- a/libavcodec/loco.c +++ b/libavcodec/loco.c @@ -45,7 +45,6 @@ enum LOCO_MODE { typedef struct LOCOContext { AVCodecContext *avctx; - AVFrame pic; int lossy; int mode; } LOCOContext; @@ -173,14 +172,10 @@ static int decode_frame(AVCodecContext *avctx, LOCOContext * const l = avctx->priv_data; const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; - AVFrame * const p = &l->pic; + AVFrame * const p = data; int decoded, ret; - if (p->data[0]) - avctx->release_buffer(avctx, p); - - p->reference = 0; - if ((ret = ff_get_buffer(avctx, p)) < 0) { + if ((ret = ff_get_buffer(avctx, p, 0)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } @@ -260,7 +255,6 @@ static int decode_frame(AVCodecContext *avctx, } *got_frame = 1; - *(AVFrame*)data = l->pic; return buf_size; buf_too_small: @@ -321,24 +315,12 @@ static av_cold int decode_init(AVCodecContext *avctx) return 0; } -static av_cold int decode_end(AVCodecContext *avctx) -{ - LOCOContext * const l = avctx->priv_data; - AVFrame *pic = &l->pic; - - if (pic->data[0]) - avctx->release_buffer(avctx, pic); - - return 0; -} - AVCodec ff_loco_decoder = { .name = "loco", .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_LOCO, .priv_data_size = sizeof(LOCOContext), .init = decode_init, - .close = decode_end, .decode = decode_frame, .capabilities = CODEC_CAP_DR1, .long_name = NULL_IF_CONFIG_SMALL("LOCO"), diff --git a/libavcodec/mace.c b/libavcodec/mace.c index 368e5d7986..559dcee567 100644 --- a/libavcodec/mace.c +++ b/libavcodec/mace.c @@ -246,7 +246,7 @@ static int mace_decode_frame(AVCodecContext *avctx, void *data, /* get output buffer */ frame->nb_samples = 3 * (buf_size << (1 - is_mace3)) / avctx->channels; - if ((ret = ff_get_buffer(avctx, frame)) < 0) { + if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } diff --git a/libavcodec/mdec.c b/libavcodec/mdec.c index f85c3bac89..3a1a7074d4 100644 --- a/libavcodec/mdec.c +++ b/libavcodec/mdec.c @@ -35,7 +35,7 @@ typedef struct MDECContext { AVCodecContext *avctx; DSPContext dsp; - AVFrame picture; + ThreadFrame frame; GetBitContext gb; ScanTable scantable; int version; @@ -135,14 +135,14 @@ static inline int decode_mb(MDECContext *a, int16_t block[6][64]) return 0; } -static inline void idct_put(MDECContext *a, int mb_x, int mb_y) +static inline void idct_put(MDECContext *a, AVFrame *frame, int mb_x, int mb_y) { int16_t (*block)[64] = a->block; - int linesize = a->picture.linesize[0]; + int linesize = frame->linesize[0]; - uint8_t *dest_y = a->picture.data[0] + (mb_y * 16 * linesize ) + mb_x * 16; - uint8_t *dest_cb = a->picture.data[1] + (mb_y * 8 * a->picture.linesize[1]) + mb_x * 8; - uint8_t *dest_cr = a->picture.data[2] + (mb_y * 8 * a->picture.linesize[2]) + mb_x * 8; + uint8_t *dest_y = frame->data[0] + (mb_y * 16* linesize ) + mb_x * 16; + uint8_t *dest_cb = frame->data[1] + (mb_y * 8 * frame->linesize[1]) + mb_x * 8; + uint8_t *dest_cr = frame->data[2] + (mb_y * 8 * frame->linesize[2]) + mb_x * 8; a->dsp.idct_put(dest_y, linesize, block[0]); a->dsp.idct_put(dest_y + 8, linesize, block[1]); @@ -150,8 +150,8 @@ static inline void idct_put(MDECContext *a, int mb_x, int mb_y) a->dsp.idct_put(dest_y + 8 * linesize + 8, linesize, block[3]); if (!(a->avctx->flags & CODEC_FLAG_GRAY)) { - a->dsp.idct_put(dest_cb, a->picture.linesize[1], block[4]); - a->dsp.idct_put(dest_cr, a->picture.linesize[2], block[5]); + a->dsp.idct_put(dest_cb, frame->linesize[1], block[4]); + a->dsp.idct_put(dest_cr, frame->linesize[2], block[5]); } } @@ -162,20 +162,15 @@ static int decode_frame(AVCodecContext *avctx, MDECContext * const a = avctx->priv_data; const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; - AVFrame *picture = data; - AVFrame * const p = &a->picture; + ThreadFrame frame = { .f = data }; int i, ret; - if (p->data[0]) - ff_thread_release_buffer(avctx, p); - - p->reference = 0; - if ((ret = ff_thread_get_buffer(avctx, p)) < 0) { + if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } - p->pict_type = AV_PICTURE_TYPE_I; - p->key_frame = 1; + frame.f->pict_type = AV_PICTURE_TYPE_I; + frame.f->key_frame = 1; av_fast_malloc(&a->bitstream_buffer, &a->bitstream_buffer_size, buf_size + FF_INPUT_BUFFER_PADDING_SIZE); if (!a->bitstream_buffer) @@ -199,14 +194,10 @@ static int decode_frame(AVCodecContext *avctx, if ((ret = decode_mb(a, a->block)) < 0) return ret; - idct_put(a, a->mb_x, a->mb_y); + idct_put(a, frame.f, a->mb_x, a->mb_y); } } - p->quality = a->qscale * FF_QP2LAMBDA; - memset(p->qscale_table, a->qscale, a->mb_width); - - *picture = a->picture; *got_frame = 1; return (get_bits_count(&a->gb) + 31) / 32 * 4; @@ -215,12 +206,10 @@ static int decode_frame(AVCodecContext *avctx, static av_cold int decode_init(AVCodecContext *avctx) { MDECContext * const a = avctx->priv_data; - AVFrame *p = &a->picture; a->mb_width = (avctx->coded_width + 15) / 16; a->mb_height = (avctx->coded_height + 15) / 16; - avctx->coded_frame = &a->picture; a->avctx = avctx; ff_dsputil_init(&a->dsp, avctx); @@ -229,8 +218,6 @@ static av_cold int decode_init(AVCodecContext *avctx) if (avctx->idct_algo == FF_IDCT_AUTO) avctx->idct_algo = FF_IDCT_SIMPLE; - p->qstride = 0; - p->qscale_table = av_mallocz(a->mb_width); avctx->pix_fmt = AV_PIX_FMT_YUVJ420P; return 0; @@ -239,13 +226,9 @@ static av_cold int decode_init(AVCodecContext *avctx) static av_cold int decode_init_thread_copy(AVCodecContext *avctx) { MDECContext * const a = avctx->priv_data; - AVFrame *p = &a->picture; - avctx->coded_frame = p; a->avctx = avctx; - p->qscale_table = av_mallocz( a->mb_width); - return 0; } @@ -253,10 +236,7 @@ static av_cold int decode_end(AVCodecContext *avctx) { MDECContext * const a = avctx->priv_data; - if (a->picture.data[0]) - avctx->release_buffer(avctx, &a->picture); av_freep(&a->bitstream_buffer); - av_freep(&a->picture.qscale_table); a->bitstream_buffer_size = 0; return 0; diff --git a/libavcodec/mimic.c b/libavcodec/mimic.c index 8ab1c9e985..ecd837088d 100644 --- a/libavcodec/mimic.c +++ b/libavcodec/mimic.c @@ -44,7 +44,7 @@ typedef struct { int cur_index; int prev_index; - AVFrame buf_ptrs [16]; + ThreadFrame frames [16]; AVPicture flipped_ptrs[16]; DECLARE_ALIGNED(16, int16_t, dct_block)[64]; @@ -109,10 +109,31 @@ static const uint8_t col_zag[64] = { 53, 60, 61, 54, 47, 55, 62, 63, }; +static av_cold int mimic_decode_end(AVCodecContext *avctx) +{ + MimicContext *ctx = avctx->priv_data; + int i; + + av_free(ctx->swap_buf); + + for (i = 0; i < FF_ARRAY_ELEMS(ctx->frames); i++) { + if (ctx->frames[i].f) + ff_thread_release_buffer(avctx, &ctx->frames[i]); + av_frame_free(&ctx->frames[i].f); + } + + if (!avctx->internal->is_copy) + ff_free_vlc(&ctx->vlc); + + return 0; +} + static av_cold int mimic_decode_init(AVCodecContext *avctx) { MimicContext *ctx = avctx->priv_data; - int ret; + int ret, i; + + avctx->internal->allocate_progress = 1; ctx->prev_index = 0; ctx->cur_index = 15; @@ -125,12 +146,21 @@ static av_cold int mimic_decode_init(AVCodecContext *avctx) ff_dsputil_init(&ctx->dsp, avctx); ff_init_scantable(ctx->dsp.idct_permutation, &ctx->scantable, col_zag); + for (i = 0; i < FF_ARRAY_ELEMS(ctx->frames); i++) { + ctx->frames[i].f = av_frame_alloc(); + if (!ctx->frames[i].f) { + mimic_decode_end(avctx); + return AVERROR(ENOMEM); + } + } + return 0; } static int mimic_decode_update_thread_context(AVCodecContext *avctx, const AVCodecContext *avctx_from) { MimicContext *dst = avctx->priv_data, *src = avctx_from->priv_data; + int i, ret; if (avctx == avctx_from) return 0; @@ -138,10 +168,16 @@ static int mimic_decode_update_thread_context(AVCodecContext *avctx, const AVCod dst->cur_index = src->next_cur_index; dst->prev_index = src->next_prev_index; - memcpy(dst->buf_ptrs, src->buf_ptrs, sizeof(src->buf_ptrs)); memcpy(dst->flipped_ptrs, src->flipped_ptrs, sizeof(src->flipped_ptrs)); - memset(&dst->buf_ptrs[dst->cur_index], 0, sizeof(AVFrame)); + for (i = 0; i < FF_ARRAY_ELEMS(dst->frames); i++) { + ff_thread_release_buffer(avctx, &dst->frames[i]); + if (src->frames[i].f->data[0]) { + ret = ff_thread_ref_frame(&dst->frames[i], &src->frames[i]); + if (ret < 0) + return ret; + } + } return 0; } @@ -264,7 +300,7 @@ static int decode(MimicContext *ctx, int quality, int num_coeffs, uint8_t *p = ctx->flipped_ptrs[index].data[0]; if (index != ctx->cur_index && p) { - ff_thread_await_progress(&ctx->buf_ptrs[index], + ff_thread_await_progress(&ctx->frames[index], cur_row, 0); p += src - ctx->flipped_ptrs[ctx->prev_index].data[plane]; @@ -275,7 +311,7 @@ static int decode(MimicContext *ctx, int quality, int num_coeffs, } } } else { - ff_thread_await_progress(&ctx->buf_ptrs[ctx->prev_index], + ff_thread_await_progress(&ctx->frames[ctx->prev_index], cur_row, 0); ctx->dsp.put_pixels_tab[1][0](dst, src, stride, 8); } @@ -285,7 +321,7 @@ static int decode(MimicContext *ctx, int quality, int num_coeffs, src += (stride - ctx->num_hblocks[plane]) << 3; dst += (stride - ctx->num_hblocks[plane]) << 3; - ff_thread_report_progress(&ctx->buf_ptrs[ctx->cur_index], + ff_thread_report_progress(&ctx->frames[ctx->cur_index], cur_row++, 0); } } @@ -357,15 +393,16 @@ static int mimic_decode_frame(AVCodecContext *avctx, void *data, return AVERROR_PATCHWELCOME; } - if (is_pframe && !ctx->buf_ptrs[ctx->prev_index].data[0]) { + if (is_pframe && !ctx->frames[ctx->prev_index].f->data[0]) { av_log(avctx, AV_LOG_ERROR, "decoding must start with keyframe\n"); return AVERROR_INVALIDDATA; } - ctx->buf_ptrs[ctx->cur_index].reference = 1; - ctx->buf_ptrs[ctx->cur_index].pict_type = is_pframe ? AV_PICTURE_TYPE_P : - AV_PICTURE_TYPE_I; - if ((res = ff_thread_get_buffer(avctx, &ctx->buf_ptrs[ctx->cur_index])) < 0) { + ff_thread_release_buffer(avctx, &ctx->frames[ctx->cur_index]); + ctx->frames[ctx->cur_index].f->pict_type = is_pframe ? AV_PICTURE_TYPE_P : + AV_PICTURE_TYPE_I; + if ((res = ff_thread_get_buffer(avctx, &ctx->frames[ctx->cur_index], + AV_GET_BUFFER_FLAG_REF)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return res; } @@ -374,7 +411,7 @@ static int mimic_decode_frame(AVCodecContext *avctx, void *data, ctx->next_cur_index = (ctx->cur_index - 1) & 15; prepare_avpic(ctx, &ctx->flipped_ptrs[ctx->cur_index], - &ctx->buf_ptrs[ctx->cur_index]); + ctx->frames[ctx->cur_index].f); ff_thread_finish_setup(avctx); @@ -388,41 +425,39 @@ static int mimic_decode_frame(AVCodecContext *avctx, void *data, init_get_bits(&ctx->gb, ctx->swap_buf, swap_buf_size << 3); res = decode(ctx, quality, num_coeffs, !is_pframe); - ff_thread_report_progress(&ctx->buf_ptrs[ctx->cur_index], INT_MAX, 0); + ff_thread_report_progress(&ctx->frames[ctx->cur_index], INT_MAX, 0); if (res < 0) { if (!(avctx->active_thread_type & FF_THREAD_FRAME)) { - ff_thread_release_buffer(avctx, &ctx->buf_ptrs[ctx->cur_index]); + ff_thread_release_buffer(avctx, &ctx->frames[ctx->cur_index]); return res; } } - *(AVFrame*)data = ctx->buf_ptrs[ctx->cur_index]; + if ((res = av_frame_ref(data, ctx->frames[ctx->cur_index].f)) < 0) + return res; *got_frame = 1; ctx->prev_index = ctx->next_prev_index; ctx->cur_index = ctx->next_cur_index; /* Only release frames that aren't used for backreferences anymore */ - if (ctx->buf_ptrs[ctx->cur_index].data[0]) - ff_thread_release_buffer(avctx, &ctx->buf_ptrs[ctx->cur_index]); + ff_thread_release_buffer(avctx, &ctx->frames[ctx->cur_index]); return buf_size; } -static av_cold int mimic_decode_end(AVCodecContext *avctx) +static av_cold int mimic_init_thread_copy(AVCodecContext *avctx) { MimicContext *ctx = avctx->priv_data; int i; - av_free(ctx->swap_buf); - - if (avctx->internal->is_copy) - return 0; - - for (i = 0; i < 16; i++) - if (ctx->buf_ptrs[i].data[0]) - ff_thread_release_buffer(avctx, &ctx->buf_ptrs[i]); - ff_free_vlc(&ctx->vlc); + for (i = 0; i < FF_ARRAY_ELEMS(ctx->frames); i++) { + ctx->frames[i].f = av_frame_alloc(); + if (!ctx->frames[i].f) { + mimic_decode_end(avctx); + return AVERROR(ENOMEM); + } + } return 0; } @@ -437,5 +472,6 @@ AVCodec ff_mimic_decoder = { .decode = mimic_decode_frame, .capabilities = CODEC_CAP_DR1 | CODEC_CAP_FRAME_THREADS, .long_name = NULL_IF_CONFIG_SMALL("Mimic"), - .update_thread_context = ONLY_IF_THREADS_ENABLED(mimic_decode_update_thread_context) + .update_thread_context = ONLY_IF_THREADS_ENABLED(mimic_decode_update_thread_context), + .init_thread_copy = ONLY_IF_THREADS_ENABLED(mimic_init_thread_copy), }; diff --git a/libavcodec/mjpegbdec.c b/libavcodec/mjpegbdec.c index 9d5a8f31ef..5edc0e4e24 100644 --- a/libavcodec/mjpegbdec.c +++ b/libavcodec/mjpegbdec.c @@ -45,10 +45,10 @@ static int mjpegb_decode_frame(AVCodecContext *avctx, int buf_size = avpkt->size; MJpegDecodeContext *s = avctx->priv_data; const uint8_t *buf_end, *buf_ptr; - AVFrame *picture = data; GetBitContext hgb; /* for the header */ uint32_t dqt_offs, dht_offs, sof_offs, sos_offs, second_field_offs; uint32_t field_size, sod_offs; + int ret; buf_ptr = buf; buf_end = buf + buf_size; @@ -136,17 +136,13 @@ read_header: //XXX FIXME factorize, this looks very similar to the EOI code - *picture= *s->picture_ptr; + if ((ret = av_frame_ref(data, s->picture_ptr)) < 0) + return ret; *got_frame = 1; - if(!s->lossless){ - picture->quality= FFMAX3(s->qscale[0], s->qscale[1], s->qscale[2]); - picture->qstride= 0; - picture->qscale_table= s->qscale_table; - memset(picture->qscale_table, picture->quality, (s->width+15)/16); - if(avctx->debug & FF_DEBUG_QP) - av_log(avctx, AV_LOG_DEBUG, "QP: %d\n", picture->quality); - picture->quality*= FF_QP2LAMBDA; + if (!s->lossless && avctx->debug & FF_DEBUG_QP) { + av_log(avctx, AV_LOG_DEBUG, "QP: %d\n", + FFMAX3(s->qscale[0], s->qscale[1], s->qscale[2])); } return buf_size; diff --git a/libavcodec/mjpegdec.c b/libavcodec/mjpegdec.c index 470529fcee..17930080f5 100644 --- a/libavcodec/mjpegdec.c +++ b/libavcodec/mjpegdec.c @@ -280,8 +280,6 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s) /* if different size, realloc/alloc picture */ /* XXX: also check h_count and v_count */ if (width != s->width || height != s->height) { - av_freep(&s->qscale_table); - s->width = width; s->height = height; s->interlaced = 0; @@ -299,7 +297,6 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s) avcodec_set_dimensions(s->avctx, width, height); - s->qscale_table = av_mallocz((s->width + 15) / 16); s->first_picture = 0; } @@ -350,10 +347,8 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s) s->avctx->pix_fmt = AV_PIX_FMT_GRAY16; } - if (s->picture_ptr->data[0]) - s->avctx->release_buffer(s->avctx, s->picture_ptr); - - if (ff_get_buffer(s->avctx, s->picture_ptr) < 0) { + av_frame_unref(s->picture_ptr); + if (ff_get_buffer(s->avctx, s->picture_ptr, AV_GET_BUFFER_FLAG_REF) < 0) { av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return -1; } @@ -1452,7 +1447,6 @@ int ff_mjpeg_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, int unescaped_buf_size; int start_code; int ret = 0; - AVFrame *picture = data; s->got_picture = 0; // picture from previous image can not be reused buf_ptr = buf; @@ -1555,21 +1549,16 @@ eoi_parser: if (s->bottom_field == !s->interlace_polarity) goto not_the_end; } - *picture = *s->picture_ptr; + if ((ret = av_frame_ref(data, s->picture_ptr)) < 0) + return ret; *got_frame = 1; - if (!s->lossless) { - picture->quality = FFMAX3(s->qscale[0], - s->qscale[1], - s->qscale[2]); - picture->qstride = 0; - picture->qscale_table = s->qscale_table; - memset(picture->qscale_table, picture->quality, - (s->width + 15) / 16); - if (avctx->debug & FF_DEBUG_QP) - av_log(avctx, AV_LOG_DEBUG, - "QP: %d\n", picture->quality); - picture->quality *= FF_QP2LAMBDA; + if (!s->lossless && + avctx->debug & FF_DEBUG_QP) { + av_log(avctx, AV_LOG_DEBUG, + "QP: %d\n", FFMAX3(s->qscale[0], + s->qscale[1], + s->qscale[2])); } goto the_end; @@ -1631,11 +1620,10 @@ av_cold int ff_mjpeg_decode_end(AVCodecContext *avctx) MJpegDecodeContext *s = avctx->priv_data; int i, j; - if (s->picture_ptr && s->picture_ptr->data[0]) - avctx->release_buffer(avctx, s->picture_ptr); + if (s->picture_ptr) + av_frame_unref(s->picture_ptr); av_free(s->buffer); - av_free(s->qscale_table); av_freep(&s->ljpeg_buffer); s->ljpeg_buffer_size = 0; diff --git a/libavcodec/mlpdec.c b/libavcodec/mlpdec.c index 130ce26d6c..160f35987e 100644 --- a/libavcodec/mlpdec.c +++ b/libavcodec/mlpdec.c @@ -991,7 +991,7 @@ static int output_data(MLPDecodeContext *m, unsigned int substr, /* get output buffer */ frame->nb_samples = s->blockpos; - if ((ret = ff_get_buffer(avctx, frame)) < 0) { + if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } diff --git a/libavcodec/mmvideo.c b/libavcodec/mmvideo.c index 784b939734..7101f8033f 100644 --- a/libavcodec/mmvideo.c +++ b/libavcodec/mmvideo.c @@ -34,6 +34,7 @@ #include "libavutil/intreadwrite.h" #include "avcodec.h" #include "bytestream.h" +#include "internal.h" #define MM_PREAMBLE_SIZE 6 @@ -60,8 +61,6 @@ static av_cold int mm_decode_init(AVCodecContext *avctx) avctx->pix_fmt = AV_PIX_FMT_PAL8; - s->frame.reference = 1; - return 0; } @@ -187,9 +186,9 @@ static int mm_decode_frame(AVCodecContext *avctx, buf_size -= MM_PREAMBLE_SIZE; bytestream2_init(&s->gb, buf, buf_size); - if (avctx->reget_buffer(avctx, &s->frame) < 0) { + if ((res = ff_reget_buffer(avctx, &s->frame)) < 0) { av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); - return -1; + return res; } switch(type) { @@ -209,8 +208,10 @@ static int mm_decode_frame(AVCodecContext *avctx, memcpy(s->frame.data[1], s->palette, AVPALETTE_SIZE); + if ((res = av_frame_ref(data, &s->frame)) < 0) + return res; + *got_frame = 1; - *(AVFrame*)data = s->frame; return buf_size; } @@ -219,8 +220,7 @@ static av_cold int mm_decode_end(AVCodecContext *avctx) { MmContext *s = avctx->priv_data; - if(s->frame.data[0]) - avctx->release_buffer(avctx, &s->frame); + av_frame_unref(&s->frame); return 0; } diff --git a/libavcodec/motion_est.c b/libavcodec/motion_est.c index d70021c4d3..99c5564544 100644 --- a/libavcodec/motion_est.c +++ b/libavcodec/motion_est.c @@ -494,16 +494,16 @@ static inline void set_p_mv_tables(MpegEncContext * s, int mx, int my, int mv4) if(mv4){ int mot_xy= s->block_index[0]; - s->current_picture.f.motion_val[0][mot_xy ][0] = mx; - s->current_picture.f.motion_val[0][mot_xy ][1] = my; - s->current_picture.f.motion_val[0][mot_xy + 1][0] = mx; - s->current_picture.f.motion_val[0][mot_xy + 1][1] = my; + s->current_picture.motion_val[0][mot_xy ][0] = mx; + s->current_picture.motion_val[0][mot_xy ][1] = my; + s->current_picture.motion_val[0][mot_xy + 1][0] = mx; + s->current_picture.motion_val[0][mot_xy + 1][1] = my; mot_xy += s->b8_stride; - s->current_picture.f.motion_val[0][mot_xy ][0] = mx; - s->current_picture.f.motion_val[0][mot_xy ][1] = my; - s->current_picture.f.motion_val[0][mot_xy + 1][0] = mx; - s->current_picture.f.motion_val[0][mot_xy + 1][1] = my; + s->current_picture.motion_val[0][mot_xy ][0] = mx; + s->current_picture.motion_val[0][mot_xy ][1] = my; + s->current_picture.motion_val[0][mot_xy + 1][0] = mx; + s->current_picture.motion_val[0][mot_xy + 1][1] = my; } } @@ -576,8 +576,8 @@ static inline int h263_mv4_search(MpegEncContext *s, int mx, int my, int shift) const int mot_stride = s->b8_stride; const int mot_xy = s->block_index[block]; - P_LEFT[0] = s->current_picture.f.motion_val[0][mot_xy - 1][0]; - P_LEFT[1] = s->current_picture.f.motion_val[0][mot_xy - 1][1]; + P_LEFT[0] = s->current_picture.motion_val[0][mot_xy - 1][0]; + P_LEFT[1] = s->current_picture.motion_val[0][mot_xy - 1][1]; if(P_LEFT[0] > (c->xmax<xmax<pred_x= pred_x4= P_LEFT[0]; c->pred_y= pred_y4= P_LEFT[1]; } else { - P_TOP[0] = s->current_picture.f.motion_val[0][mot_xy - mot_stride ][0]; - P_TOP[1] = s->current_picture.f.motion_val[0][mot_xy - mot_stride ][1]; - P_TOPRIGHT[0] = s->current_picture.f.motion_val[0][mot_xy - mot_stride + off[block]][0]; - P_TOPRIGHT[1] = s->current_picture.f.motion_val[0][mot_xy - mot_stride + off[block]][1]; + P_TOP[0] = s->current_picture.motion_val[0][mot_xy - mot_stride ][0]; + P_TOP[1] = s->current_picture.motion_val[0][mot_xy - mot_stride ][1]; + P_TOPRIGHT[0] = s->current_picture.motion_val[0][mot_xy - mot_stride + off[block]][0]; + P_TOPRIGHT[1] = s->current_picture.motion_val[0][mot_xy - mot_stride + off[block]][1]; if(P_TOP[1] > (c->ymax<ymax<xmin<xmin< (c->xmax<xmax<current_picture.f.motion_val[0][s->block_index[block]][0] = mx4; - s->current_picture.f.motion_val[0][s->block_index[block]][1] = my4; + s->current_picture.motion_val[0][s->block_index[block]][0] = mx4; + s->current_picture.motion_val[0][s->block_index[block]][1] = my4; if(mx4 != mx || my4 != my) same=0; } @@ -894,16 +894,16 @@ void ff_estimate_p_frame_motion(MpegEncContext * s, const int mot_stride = s->b8_stride; const int mot_xy = s->block_index[0]; - P_LEFT[0] = s->current_picture.f.motion_val[0][mot_xy - 1][0]; - P_LEFT[1] = s->current_picture.f.motion_val[0][mot_xy - 1][1]; + P_LEFT[0] = s->current_picture.motion_val[0][mot_xy - 1][0]; + P_LEFT[1] = s->current_picture.motion_val[0][mot_xy - 1][1]; if(P_LEFT[0] > (c->xmax<xmax<first_slice_line) { - P_TOP[0] = s->current_picture.f.motion_val[0][mot_xy - mot_stride ][0]; - P_TOP[1] = s->current_picture.f.motion_val[0][mot_xy - mot_stride ][1]; - P_TOPRIGHT[0] = s->current_picture.f.motion_val[0][mot_xy - mot_stride + 2][0]; - P_TOPRIGHT[1] = s->current_picture.f.motion_val[0][mot_xy - mot_stride + 2][1]; + P_TOP[0] = s->current_picture.motion_val[0][mot_xy - mot_stride ][0]; + P_TOP[1] = s->current_picture.motion_val[0][mot_xy - mot_stride ][1]; + P_TOPRIGHT[0] = s->current_picture.motion_val[0][mot_xy - mot_stride + 2][0]; + P_TOPRIGHT[1] = s->current_picture.motion_val[0][mot_xy - mot_stride + 2][1]; if(P_TOP[1] > (c->ymax<ymax<xmin<xmin< (c->ymax<ymax<current_picture.f.mb_type[mb_y*s->mb_stride + mb_x] = CANDIDATE_MB_TYPE_INTRA; //FIXME cleanup + s->current_picture.mb_type[mb_y*s->mb_stride + mb_x] = CANDIDATE_MB_TYPE_INTRA; //FIXME cleanup }else - s->current_picture.f.mb_type[mb_y*s->mb_stride + mb_x] = 0; + s->current_picture.mb_type[mb_y*s->mb_stride + mb_x] = 0; { int p_score= FFMIN(vard, varc-500+(s->lambda2>>FF_LAMBDA_SHIFT)*100); @@ -1403,7 +1403,7 @@ static inline int direct_search(MpegEncContext * s, int mb_x, int mb_y) ymin= xmin=(-32)>>shift; ymax= xmax= 31>>shift; - if (IS_8X8(s->next_picture.f.mb_type[mot_xy])) { + if (IS_8X8(s->next_picture.mb_type[mot_xy])) { s->mv_type= MV_TYPE_8X8; }else{ s->mv_type= MV_TYPE_16X16; @@ -1413,8 +1413,8 @@ static inline int direct_search(MpegEncContext * s, int mb_x, int mb_y) int index= s->block_index[i]; int min, max; - c->co_located_mv[i][0] = s->next_picture.f.motion_val[0][index][0]; - c->co_located_mv[i][1] = s->next_picture.f.motion_val[0][index][1]; + c->co_located_mv[i][0] = s->next_picture.motion_val[0][index][0]; + c->co_located_mv[i][1] = s->next_picture.motion_val[0][index][1]; c->direct_basis_mv[i][0]= c->co_located_mv[i][0]*time_pb/time_pp + ((i& 1)<<(shift+3)); c->direct_basis_mv[i][1]= c->co_located_mv[i][1]*time_pb/time_pp + ((i>>1)<<(shift+3)); // c->direct_basis_mv[1][i][0]= c->co_located_mv[i][0]*(time_pb - time_pp)/time_pp + ((i &1)<<(shift+3); @@ -1503,7 +1503,7 @@ void ff_estimate_b_frame_motion(MpegEncContext * s, c->skip=0; - if (s->codec_id == AV_CODEC_ID_MPEG4 && s->next_picture.f.mbskip_table[xy]) { + if (s->codec_id == AV_CODEC_ID_MPEG4 && s->next_picture.mbskip_table[xy]) { int score= direct_search(s, mb_x, mb_y); //FIXME just check 0,0 score= ((unsigned)(score*score + 128*256))>>16; @@ -1674,14 +1674,14 @@ void ff_fix_long_p_mvs(MpegEncContext * s) int block; for(block=0; block<4; block++){ int off= (block& 1) + (block>>1)*wrap; - int mx = s->current_picture.f.motion_val[0][ xy + off ][0]; - int my = s->current_picture.f.motion_val[0][ xy + off ][1]; + int mx = s->current_picture.motion_val[0][ xy + off ][0]; + int my = s->current_picture.motion_val[0][ xy + off ][1]; if( mx >=range || mx <-range || my >=range || my <-range){ s->mb_type[i] &= ~CANDIDATE_MB_TYPE_INTER4V; s->mb_type[i] |= CANDIDATE_MB_TYPE_INTRA; - s->current_picture.f.mb_type[i] = CANDIDATE_MB_TYPE_INTRA; + s->current_picture.mb_type[i] = CANDIDATE_MB_TYPE_INTRA; } } } diff --git a/libavcodec/motionpixels.c b/libavcodec/motionpixels.c index c2bd0f4d2b..c205735c90 100644 --- a/libavcodec/motionpixels.c +++ b/libavcodec/motionpixels.c @@ -22,6 +22,7 @@ #include "avcodec.h" #include "get_bits.h" #include "dsputil.h" +#include "internal.h" #define MAX_HUFF_CODES 16 @@ -244,13 +245,11 @@ static int mp_decode_frame(AVCodecContext *avctx, int buf_size = avpkt->size; MotionPixelsContext *mp = avctx->priv_data; GetBitContext gb; - int i, count1, count2, sz; + int i, count1, count2, sz, ret; - mp->frame.reference = 1; - mp->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE; - if (avctx->reget_buffer(avctx, &mp->frame)) { + if ((ret = ff_reget_buffer(avctx, &mp->frame)) < 0) { av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); - return -1; + return ret; } /* le32 bitstream msb first */ @@ -295,8 +294,9 @@ static int mp_decode_frame(AVCodecContext *avctx, ff_free_vlc(&mp->vlc); end: + if ((ret = av_frame_ref(data, &mp->frame)) < 0) + return ret; *got_frame = 1; - *(AVFrame *)data = mp->frame; return buf_size; } @@ -308,8 +308,7 @@ static av_cold int mp_decode_end(AVCodecContext *avctx) av_freep(&mp->vpt); av_freep(&mp->hpt); av_freep(&mp->bswapbuf); - if (mp->frame.data[0]) - avctx->release_buffer(avctx, &mp->frame); + av_frame_unref(&mp->frame); return 0; } diff --git a/libavcodec/mpc7.c b/libavcodec/mpc7.c index f151f9c304..4ebb254107 100644 --- a/libavcodec/mpc7.c +++ b/libavcodec/mpc7.c @@ -229,7 +229,7 @@ static int mpc7_decode_frame(AVCodecContext * avctx, void *data, /* get output buffer */ frame->nb_samples = last_frame ? c->lastframelen : MPC_FRAME_SIZE; - if ((ret = ff_get_buffer(avctx, frame)) < 0) { + if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } diff --git a/libavcodec/mpc8.c b/libavcodec/mpc8.c index 1b32c4b3fa..7f920d8b54 100644 --- a/libavcodec/mpc8.c +++ b/libavcodec/mpc8.c @@ -249,7 +249,7 @@ static int mpc8_decode_frame(AVCodecContext * avctx, void *data, /* get output buffer */ frame->nb_samples = MPC_FRAME_SIZE; - if ((res = ff_get_buffer(avctx, frame)) < 0) { + if ((res = ff_get_buffer(avctx, frame, 0)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return res; } diff --git a/libavcodec/mpeg12.c b/libavcodec/mpeg12.c index ce136e7c30..c32055d609 100644 --- a/libavcodec/mpeg12.c +++ b/libavcodec/mpeg12.c @@ -746,19 +746,19 @@ static int mpeg_decode_mb(MpegEncContext *s, int16_t block[12][64]) if (s->mb_skip_run-- != 0) { if (s->pict_type == AV_PICTURE_TYPE_P) { s->mb_skipped = 1; - s->current_picture.f.mb_type[s->mb_x + s->mb_y * s->mb_stride] = MB_TYPE_SKIP | MB_TYPE_L0 | MB_TYPE_16x16; + s->current_picture.mb_type[s->mb_x + s->mb_y * s->mb_stride] = MB_TYPE_SKIP | MB_TYPE_L0 | MB_TYPE_16x16; } else { int mb_type; if (s->mb_x) - mb_type = s->current_picture.f.mb_type[s->mb_x + s->mb_y * s->mb_stride - 1]; + mb_type = s->current_picture.mb_type[s->mb_x + s->mb_y * s->mb_stride - 1]; else - mb_type = s->current_picture.f.mb_type[s->mb_width + (s->mb_y - 1) * s->mb_stride - 1]; // FIXME not sure if this is allowed in MPEG at all + mb_type = s->current_picture.mb_type[s->mb_width + (s->mb_y - 1) * s->mb_stride - 1]; // FIXME not sure if this is allowed in MPEG at all if (IS_INTRA(mb_type)) return -1; - s->current_picture.f.mb_type[s->mb_x + s->mb_y*s->mb_stride] = + s->current_picture.mb_type[s->mb_x + s->mb_y*s->mb_stride] = mb_type | MB_TYPE_SKIP; -// assert(s->current_picture.f.mb_type[s->mb_x + s->mb_y * s->mb_stride - 1] & (MB_TYPE_16x16 | MB_TYPE_16x8)); +// assert(s->current_picture.mb_type[s->mb_x + s->mb_y * s->mb_stride - 1] & (MB_TYPE_16x16 | MB_TYPE_16x8)); if ((s->mv[0][0][0] | s->mv[0][0][1] | s->mv[1][0][0] | s->mv[1][0][1]) == 0) s->mb_skipped = 1; @@ -1101,7 +1101,7 @@ static int mpeg_decode_mb(MpegEncContext *s, int16_t block[12][64]) } } - s->current_picture.f.mb_type[s->mb_x + s->mb_y * s->mb_stride] = mb_type; + s->current_picture.mb_type[s->mb_x + s->mb_y * s->mb_stride] = mb_type; return 0; } @@ -1576,6 +1576,8 @@ static int mpeg_field_start(MpegEncContext *s, const uint8_t *buf, int buf_size) /* start frame decoding */ if (s->first_field || s->picture_structure == PICT_FRAME) { + AVFrameSideData *pan_scan; + if (ff_MPV_frame_start(s, avctx) < 0) return -1; @@ -1594,7 +1596,12 @@ static int mpeg_field_start(MpegEncContext *s, const uint8_t *buf, int buf_size) } } - *s->current_picture_ptr->f.pan_scan = s1->pan_scan; + pan_scan = av_frame_new_side_data(&s->current_picture_ptr->f, + AV_FRAME_DATA_PANSCAN, + sizeof(s1->pan_scan)); + if (!pan_scan) + return AVERROR(ENOMEM); + memcpy(pan_scan->data, &s1->pan_scan, sizeof(s1->pan_scan)); if (HAVE_THREADS && (avctx->active_thread_type & FF_THREAD_FRAME)) ff_thread_finish_setup(avctx); @@ -1736,7 +1743,7 @@ static int mpeg_decode_slice(MpegEncContext *s, int mb_y, if (mpeg_decode_mb(s, s->block) < 0) return -1; - if (s->current_picture.f.motion_val[0] && !s->encoding) { // note motion_val is normally NULL unless we want to extract the MVs + if (s->current_picture.motion_val[0] && !s->encoding) { // note motion_val is normally NULL unless we want to extract the MVs const int wrap = s->b8_stride; int xy = s->mb_x * 2 + s->mb_y * 2 * wrap; int b8_xy = 4 * (s->mb_x + s->mb_y * s->mb_stride); @@ -1754,12 +1761,12 @@ static int mpeg_decode_slice(MpegEncContext *s, int mb_y, motion_y = s->mv[dir][i][1]; } - s->current_picture.f.motion_val[dir][xy ][0] = motion_x; - s->current_picture.f.motion_val[dir][xy ][1] = motion_y; - s->current_picture.f.motion_val[dir][xy + 1][0] = motion_x; - s->current_picture.f.motion_val[dir][xy + 1][1] = motion_y; - s->current_picture.f.ref_index [dir][b8_xy ] = - s->current_picture.f.ref_index [dir][b8_xy + 1] = s->field_select[dir][i]; + s->current_picture.motion_val[dir][xy ][0] = motion_x; + s->current_picture.motion_val[dir][xy ][1] = motion_y; + s->current_picture.motion_val[dir][xy + 1][0] = motion_x; + s->current_picture.motion_val[dir][xy + 1][1] = motion_y; + s->current_picture.ref_index [dir][b8_xy ] = + s->current_picture.ref_index [dir][b8_xy + 1] = s->field_select[dir][i]; assert(s->field_select[dir][i] == 0 || s->field_select[dir][i] == 1); } xy += wrap; @@ -1927,23 +1934,25 @@ static int slice_end(AVCodecContext *avctx, AVFrame *pict) if (/*s->mb_y << field_pic == s->mb_height &&*/ !s->first_field) { /* end of image */ - s->current_picture_ptr->f.qscale_type = FF_QSCALE_TYPE_MPEG2; - ff_er_frame_end(&s->er); ff_MPV_frame_end(s); if (s->pict_type == AV_PICTURE_TYPE_B || s->low_delay) { - *pict = s->current_picture_ptr->f; - ff_print_debug_info(s, pict); + int ret = av_frame_ref(pict, &s->current_picture_ptr->f); + if (ret < 0) + return ret; + ff_print_debug_info(s, s->current_picture_ptr); } else { if (avctx->active_thread_type & FF_THREAD_FRAME) s->picture_number++; /* latency of 1 frame for I- and P-frames */ /* XXX: use another variable than picture_number */ if (s->last_picture_ptr != NULL) { - *pict = s->last_picture_ptr->f; - ff_print_debug_info(s, pict); + int ret = av_frame_ref(pict, &s->last_picture_ptr->f); + if (ret < 0) + return ret; + ff_print_debug_info(s, s->last_picture_ptr); } } @@ -2230,7 +2239,10 @@ static int decode_chunks(AVCodecContext *avctx, if (CONFIG_MPEG_VDPAU_DECODER && avctx->codec->capabilities & CODEC_CAP_HWACCEL_VDPAU) ff_vdpau_mpeg_picture_complete(s2, buf, buf_size, s->slice_count); - if (slice_end(avctx, picture)) { + ret = slice_end(avctx, picture); + if (ret < 0) + return ret; + else if (ret) { if (s2->last_picture_ptr || s2->low_delay) //FIXME merge with the stuff in mpeg_decode_slice *got_output = 1; } @@ -2450,7 +2462,10 @@ static int mpeg_decode_frame(AVCodecContext *avctx, if (buf_size == 0 || (buf_size == 4 && AV_RB32(buf) == SEQ_END_CODE)) { /* special case for last picture */ if (s2->low_delay == 0 && s2->next_picture_ptr) { - *picture = s2->next_picture_ptr->f; + int ret = av_frame_ref(picture, &s2->next_picture_ptr->f); + if (ret < 0) + return ret; + s2->next_picture_ptr = NULL; *got_output = 1; diff --git a/libavcodec/mpeg4video.c b/libavcodec/mpeg4video.c index d7c928df03..628ca679a7 100644 --- a/libavcodec/mpeg4video.c +++ b/libavcodec/mpeg4video.c @@ -89,7 +89,7 @@ static inline void ff_mpeg4_set_one_direct_mv(MpegEncContext *s, int mx, int my, uint16_t time_pb= s->pb_time; int p_mx, p_my; - p_mx = s->next_picture.f.motion_val[0][xy][0]; + p_mx = s->next_picture.motion_val[0][xy][0]; if((unsigned)(p_mx + tab_bias) < tab_size){ s->mv[0][i][0] = s->direct_scale_mv[0][p_mx + tab_bias] + mx; s->mv[1][i][0] = mx ? s->mv[0][i][0] - p_mx @@ -99,7 +99,7 @@ static inline void ff_mpeg4_set_one_direct_mv(MpegEncContext *s, int mx, int my, s->mv[1][i][0] = mx ? s->mv[0][i][0] - p_mx : p_mx*(time_pb - time_pp)/time_pp; } - p_my = s->next_picture.f.motion_val[0][xy][1]; + p_my = s->next_picture.motion_val[0][xy][1]; if((unsigned)(p_my + tab_bias) < tab_size){ s->mv[0][i][1] = s->direct_scale_mv[0][p_my + tab_bias] + my; s->mv[1][i][1] = my ? s->mv[0][i][1] - p_my @@ -120,7 +120,7 @@ static inline void ff_mpeg4_set_one_direct_mv(MpegEncContext *s, int mx, int my, */ int ff_mpeg4_set_direct_mv(MpegEncContext *s, int mx, int my){ const int mb_index= s->mb_x + s->mb_y*s->mb_stride; - const int colocated_mb_type = s->next_picture.f.mb_type[mb_index]; + const int colocated_mb_type = s->next_picture.mb_type[mb_index]; uint16_t time_pp; uint16_t time_pb; int i; @@ -137,7 +137,7 @@ int ff_mpeg4_set_direct_mv(MpegEncContext *s, int mx, int my){ } else if(IS_INTERLACED(colocated_mb_type)){ s->mv_type = MV_TYPE_FIELD; for(i=0; i<2; i++){ - int field_select = s->next_picture.f.ref_index[0][4 * mb_index + 2 * i]; + int field_select = s->next_picture.ref_index[0][4 * mb_index + 2 * i]; s->field_select[0][i]= field_select; s->field_select[1][i]= i; if(s->top_field_first){ diff --git a/libavcodec/mpeg4videodec.c b/libavcodec/mpeg4videodec.c index 17b119072f..8ebae2e085 100644 --- a/libavcodec/mpeg4videodec.c +++ b/libavcodec/mpeg4videodec.c @@ -21,6 +21,7 @@ */ #include "error_resilience.h" +#include "internal.h" #include "mpegvideo.h" #include "mpeg4video.h" #include "h263.h" @@ -56,7 +57,7 @@ void ff_mpeg4_pred_ac(MpegEncContext * s, int16_t *block, int n, { int i; int16_t *ac_val, *ac_val1; - int8_t * const qscale_table = s->current_picture.f.qscale_table; + int8_t * const qscale_table = s->current_picture.qscale_table; /* find prediction */ ac_val = s->ac_val[0][0] + s->block_index[n] * 16; @@ -377,9 +378,9 @@ int ff_mpeg4_decode_video_packet_header(MpegEncContext *s) if(s->pict_type == AV_PICTURE_TYPE_B){ int mb_x = 0, mb_y = 0; - while (s->next_picture.f.mbskip_table[s->mb_index2xy[mb_num]]) { + while (s->next_picture.mbskip_table[s->mb_index2xy[mb_num]]) { if (!mb_x) - ff_thread_await_progress(&s->next_picture_ptr->f, mb_y++, 0); + ff_thread_await_progress(&s->next_picture_ptr->tf, mb_y++, 0); mb_num++; if (++mb_x == s->mb_width) mb_x = 0; } @@ -572,13 +573,13 @@ static int mpeg4_decode_partition_a(MpegEncContext *s){ }while(cbpc == 8); s->cbp_table[xy]= cbpc & 3; - s->current_picture.f.mb_type[xy] = MB_TYPE_INTRA; + s->current_picture.mb_type[xy] = MB_TYPE_INTRA; s->mb_intra = 1; if(cbpc & 4) { ff_set_qscale(s, s->qscale + quant_tab[get_bits(&s->gb, 2)]); } - s->current_picture.f.qscale_table[xy]= s->qscale; + s->current_picture.qscale_table[xy]= s->qscale; s->mbintra_table[xy]= 1; for(i=0; i<6; i++){ @@ -594,7 +595,7 @@ static int mpeg4_decode_partition_a(MpegEncContext *s){ s->pred_dir_table[xy]= dir; }else{ /* P/S_TYPE */ int mx, my, pred_x, pred_y, bits; - int16_t * const mot_val = s->current_picture.f.motion_val[0][s->block_index[0]]; + int16_t * const mot_val = s->current_picture.motion_val[0][s->block_index[0]]; const int stride= s->b8_stride*2; try_again: @@ -606,11 +607,11 @@ try_again: if(bits&0x10000){ /* skip mb */ if(s->pict_type==AV_PICTURE_TYPE_S && s->vol_sprite_usage==GMC_SPRITE){ - s->current_picture.f.mb_type[xy] = MB_TYPE_SKIP | MB_TYPE_16x16 | MB_TYPE_GMC | MB_TYPE_L0; + s->current_picture.mb_type[xy] = MB_TYPE_SKIP | MB_TYPE_16x16 | MB_TYPE_GMC | MB_TYPE_L0; mx= get_amv(s, 0); my= get_amv(s, 1); }else{ - s->current_picture.f.mb_type[xy] = MB_TYPE_SKIP | MB_TYPE_16x16 | MB_TYPE_L0; + s->current_picture.mb_type[xy] = MB_TYPE_SKIP | MB_TYPE_16x16 | MB_TYPE_L0; mx=my=0; } mot_val[0 ]= mot_val[2 ]= @@ -636,7 +637,7 @@ try_again: s->mb_intra = ((cbpc & 4) != 0); if(s->mb_intra){ - s->current_picture.f.mb_type[xy] = MB_TYPE_INTRA; + s->current_picture.mb_type[xy] = MB_TYPE_INTRA; s->mbintra_table[xy]= 1; mot_val[0 ]= mot_val[2 ]= mot_val[0+stride]= mot_val[2+stride]= 0; @@ -662,11 +663,11 @@ try_again: my = ff_h263_decode_motion(s, pred_y, s->f_code); if (my >= 0xffff) return -1; - s->current_picture.f.mb_type[xy] = MB_TYPE_16x16 | MB_TYPE_L0; + s->current_picture.mb_type[xy] = MB_TYPE_16x16 | MB_TYPE_L0; } else { mx = get_amv(s, 0); my = get_amv(s, 1); - s->current_picture.f.mb_type[xy] = MB_TYPE_16x16 | MB_TYPE_GMC | MB_TYPE_L0; + s->current_picture.mb_type[xy] = MB_TYPE_16x16 | MB_TYPE_GMC | MB_TYPE_L0; } mot_val[0 ]= mot_val[2 ] = @@ -675,7 +676,7 @@ try_again: mot_val[1+stride]= mot_val[3+stride]= my; } else { int i; - s->current_picture.f.mb_type[xy] = MB_TYPE_8x8 | MB_TYPE_L0; + s->current_picture.mb_type[xy] = MB_TYPE_8x8 | MB_TYPE_L0; for(i=0;i<4;i++) { int16_t *mot_val= ff_h263_pred_motion(s, i, 0, &pred_x, &pred_y); mx = ff_h263_decode_motion(s, pred_x, s->f_code); @@ -727,9 +728,9 @@ static int mpeg4_decode_partition_b(MpegEncContext *s, int mb_count){ } s->cbp_table[xy]|= cbpy<<2; - s->current_picture.f.mb_type[xy] |= ac_pred*MB_TYPE_ACPRED; + s->current_picture.mb_type[xy] |= ac_pred*MB_TYPE_ACPRED; }else{ /* P || S_TYPE */ - if (IS_INTRA(s->current_picture.f.mb_type[xy])) { + if (IS_INTRA(s->current_picture.mb_type[xy])) { int dir=0,i; int ac_pred = get_bits1(&s->gb); int cbpy = get_vlc2(&s->gb, ff_h263_cbpy_vlc.table, CBPY_VLC_BITS, 1); @@ -742,7 +743,7 @@ static int mpeg4_decode_partition_b(MpegEncContext *s, int mb_count){ if(s->cbp_table[xy] & 8) { ff_set_qscale(s, s->qscale + quant_tab[get_bits(&s->gb, 2)]); } - s->current_picture.f.qscale_table[xy] = s->qscale; + s->current_picture.qscale_table[xy] = s->qscale; for(i=0; i<6; i++){ int dc_pred_dir; @@ -756,10 +757,10 @@ static int mpeg4_decode_partition_b(MpegEncContext *s, int mb_count){ } s->cbp_table[xy]&= 3; //remove dquant s->cbp_table[xy]|= cbpy<<2; - s->current_picture.f.mb_type[xy] |= ac_pred*MB_TYPE_ACPRED; + s->current_picture.mb_type[xy] |= ac_pred*MB_TYPE_ACPRED; s->pred_dir_table[xy]= dir; - } else if (IS_SKIP(s->current_picture.f.mb_type[xy])) { - s->current_picture.f.qscale_table[xy] = s->qscale; + } else if (IS_SKIP(s->current_picture.mb_type[xy])) { + s->current_picture.qscale_table[xy] = s->qscale; s->cbp_table[xy]= 0; }else{ int cbpy = get_vlc2(&s->gb, ff_h263_cbpy_vlc.table, CBPY_VLC_BITS, 1); @@ -772,7 +773,7 @@ static int mpeg4_decode_partition_b(MpegEncContext *s, int mb_count){ if(s->cbp_table[xy] & 8) { ff_set_qscale(s, s->qscale + quant_tab[get_bits(&s->gb, 2)]); } - s->current_picture.f.qscale_table[xy] = s->qscale; + s->current_picture.qscale_table[xy] = s->qscale; s->cbp_table[xy]&= 3; //remove dquant s->cbp_table[xy]|= (cbpy^0xf)<<2; @@ -1071,20 +1072,20 @@ static int mpeg4_decode_partitioned_mb(MpegEncContext *s, int16_t block[6][64]) int cbp, mb_type; const int xy= s->mb_x + s->mb_y*s->mb_stride; - mb_type = s->current_picture.f.mb_type[xy]; + mb_type = s->current_picture.mb_type[xy]; cbp = s->cbp_table[xy]; s->use_intra_dc_vlc= s->qscale < s->intra_dc_threshold; - if (s->current_picture.f.qscale_table[xy] != s->qscale) { - ff_set_qscale(s, s->current_picture.f.qscale_table[xy]); + if (s->current_picture.qscale_table[xy] != s->qscale) { + ff_set_qscale(s, s->current_picture.qscale_table[xy]); } if (s->pict_type == AV_PICTURE_TYPE_P || s->pict_type==AV_PICTURE_TYPE_S) { int i; for(i=0; i<4; i++){ - s->mv[0][i][0] = s->current_picture.f.motion_val[0][s->block_index[i]][0]; - s->mv[0][i][1] = s->current_picture.f.motion_val[0][s->block_index[i]][1]; + s->mv[0][i][0] = s->current_picture.motion_val[0][s->block_index[i]][0]; + s->mv[0][i][1] = s->current_picture.motion_val[0][s->block_index[i]][1]; } s->mb_intra = IS_INTRA(mb_type); @@ -1102,7 +1103,7 @@ static int mpeg4_decode_partitioned_mb(MpegEncContext *s, int16_t block[6][64]) s->mb_skipped = 1; } }else if(s->mb_intra){ - s->ac_pred = IS_ACPRED(s->current_picture.f.mb_type[xy]); + s->ac_pred = IS_ACPRED(s->current_picture.mb_type[xy]); }else if(!s->mb_intra){ // s->mcsel= 0; //FIXME do we need to init that @@ -1115,7 +1116,7 @@ static int mpeg4_decode_partitioned_mb(MpegEncContext *s, int16_t block[6][64]) } } else { /* I-Frame */ s->mb_intra = 1; - s->ac_pred = IS_ACPRED(s->current_picture.f.mb_type[xy]); + s->ac_pred = IS_ACPRED(s->current_picture.mb_type[xy]); } if (!IS_SKIP(mb_type)) { @@ -1168,14 +1169,14 @@ static int mpeg4_decode_mb(MpegEncContext *s, s->mv_dir = MV_DIR_FORWARD; s->mv_type = MV_TYPE_16X16; if(s->pict_type==AV_PICTURE_TYPE_S && s->vol_sprite_usage==GMC_SPRITE){ - s->current_picture.f.mb_type[xy] = MB_TYPE_SKIP | MB_TYPE_GMC | MB_TYPE_16x16 | MB_TYPE_L0; + s->current_picture.mb_type[xy] = MB_TYPE_SKIP | MB_TYPE_GMC | MB_TYPE_16x16 | MB_TYPE_L0; s->mcsel=1; s->mv[0][0][0]= get_amv(s, 0); s->mv[0][0][1]= get_amv(s, 1); s->mb_skipped = 0; }else{ - s->current_picture.f.mb_type[xy] = MB_TYPE_SKIP | MB_TYPE_16x16 | MB_TYPE_L0; + s->current_picture.mb_type[xy] = MB_TYPE_SKIP | MB_TYPE_16x16 | MB_TYPE_L0; s->mcsel=0; s->mv[0][0][0] = 0; s->mv[0][0][1] = 0; @@ -1210,7 +1211,7 @@ static int mpeg4_decode_mb(MpegEncContext *s, s->mv_dir = MV_DIR_FORWARD; if ((cbpc & 16) == 0) { if(s->mcsel){ - s->current_picture.f.mb_type[xy] = MB_TYPE_GMC | MB_TYPE_16x16 | MB_TYPE_L0; + s->current_picture.mb_type[xy] = MB_TYPE_GMC | MB_TYPE_16x16 | MB_TYPE_L0; /* 16x16 global motion prediction */ s->mv_type = MV_TYPE_16X16; mx= get_amv(s, 0); @@ -1218,7 +1219,7 @@ static int mpeg4_decode_mb(MpegEncContext *s, s->mv[0][0][0] = mx; s->mv[0][0][1] = my; }else if((!s->progressive_sequence) && get_bits1(&s->gb)){ - s->current_picture.f.mb_type[xy] = MB_TYPE_16x8 | MB_TYPE_L0 | MB_TYPE_INTERLACED; + s->current_picture.mb_type[xy] = MB_TYPE_16x8 | MB_TYPE_L0 | MB_TYPE_INTERLACED; /* 16x8 field motion prediction */ s->mv_type= MV_TYPE_FIELD; @@ -1240,7 +1241,7 @@ static int mpeg4_decode_mb(MpegEncContext *s, s->mv[0][i][1] = my; } }else{ - s->current_picture.f.mb_type[xy] = MB_TYPE_16x16 | MB_TYPE_L0; + s->current_picture.mb_type[xy] = MB_TYPE_16x16 | MB_TYPE_L0; /* 16x16 motion prediction */ s->mv_type = MV_TYPE_16X16; ff_h263_pred_motion(s, 0, 0, &pred_x, &pred_y); @@ -1257,7 +1258,7 @@ static int mpeg4_decode_mb(MpegEncContext *s, s->mv[0][0][1] = my; } } else { - s->current_picture.f.mb_type[xy] = MB_TYPE_8x8 | MB_TYPE_L0; + s->current_picture.mb_type[xy] = MB_TYPE_8x8 | MB_TYPE_L0; s->mv_type = MV_TYPE_8X8; for(i=0;i<4;i++) { mot_val = ff_h263_pred_motion(s, i, 0, &pred_x, &pred_y); @@ -1290,11 +1291,11 @@ static int mpeg4_decode_mb(MpegEncContext *s, s->last_mv[i][1][1]= 0; } - ff_thread_await_progress(&s->next_picture_ptr->f, s->mb_y, 0); + ff_thread_await_progress(&s->next_picture_ptr->tf, s->mb_y, 0); } /* if we skipped it in the future P Frame than skip it now too */ - s->mb_skipped = s->next_picture.f.mbskip_table[s->mb_y * s->mb_stride + s->mb_x]; // Note, skiptab=0 if last was GMC + s->mb_skipped = s->next_picture.mbskip_table[s->mb_y * s->mb_stride + s->mb_x]; // Note, skiptab=0 if last was GMC if(s->mb_skipped){ /* skip mb */ @@ -1307,7 +1308,7 @@ static int mpeg4_decode_mb(MpegEncContext *s, s->mv[0][0][1] = 0; s->mv[1][0][0] = 0; s->mv[1][0][1] = 0; - s->current_picture.f.mb_type[xy] = MB_TYPE_SKIP | MB_TYPE_16x16 | MB_TYPE_L0; + s->current_picture.mb_type[xy] = MB_TYPE_SKIP | MB_TYPE_16x16 | MB_TYPE_L0; goto end; } @@ -1413,7 +1414,7 @@ static int mpeg4_decode_mb(MpegEncContext *s, s->mv_dir = MV_DIR_FORWARD | MV_DIR_BACKWARD | MV_DIRECT; mb_type |= ff_mpeg4_set_direct_mv(s, mx, my); } - s->current_picture.f.mb_type[xy] = mb_type; + s->current_picture.mb_type[xy] = mb_type; } else { /* I-Frame */ do{ cbpc = get_vlc2(&s->gb, ff_h263_intra_MCBPC_vlc.table, INTRA_MCBPC_VLC_BITS, 2); @@ -1428,9 +1429,9 @@ static int mpeg4_decode_mb(MpegEncContext *s, intra: s->ac_pred = get_bits1(&s->gb); if(s->ac_pred) - s->current_picture.f.mb_type[xy] = MB_TYPE_INTRA | MB_TYPE_ACPRED; + s->current_picture.mb_type[xy] = MB_TYPE_INTRA | MB_TYPE_ACPRED; else - s->current_picture.f.mb_type[xy] = MB_TYPE_INTRA; + s->current_picture.mb_type[xy] = MB_TYPE_INTRA; cbpy = get_vlc2(&s->gb, ff_h263_cbpy_vlc.table, CBPY_VLC_BITS, 1); if(cbpy<0){ @@ -1471,12 +1472,12 @@ end: if(mpeg4_is_resync(s)){ const int delta= s->mb_x + 1 == s->mb_width ? 2 : 1; - if (s->pict_type == AV_PICTURE_TYPE_B && s->next_picture.f.mbskip_table[xy + delta]) { - ff_thread_await_progress(&s->next_picture_ptr->f, + if (s->pict_type == AV_PICTURE_TYPE_B && s->next_picture.mbskip_table[xy + delta]) { + ff_thread_await_progress(&s->next_picture_ptr->tf, (s->mb_x + delta >= s->mb_width) ? FFMIN(s->mb_y+1, s->mb_height-1) : s->mb_y, 0); } - if (s->pict_type == AV_PICTURE_TYPE_B && s->next_picture.f.mbskip_table[xy + delta]) + if (s->pict_type == AV_PICTURE_TYPE_B && s->next_picture.mbskip_table[xy + delta]) return SLICE_OK; return SLICE_END; } @@ -2236,6 +2237,8 @@ static av_cold int decode_init(AVCodecContext *avctx) s->time_increment_bits = 4; /* default value for broken headers */ avctx->chroma_sample_location = AVCHROMA_LOC_LEFT; + avctx->internal->allocate_progress = 1; + return 0; } diff --git a/libavcodec/mpeg4videoenc.c b/libavcodec/mpeg4videoenc.c index 9bb1f9a0bc..fb4d7a8743 100644 --- a/libavcodec/mpeg4videoenc.c +++ b/libavcodec/mpeg4videoenc.c @@ -126,7 +126,7 @@ static inline int decide_ac_pred(MpegEncContext * s, int16_t block[6][64], const { int score= 0; int i, n; - int8_t * const qscale_table = s->current_picture.f.qscale_table; + int8_t * const qscale_table = s->current_picture.qscale_table; memcpy(zigzag_last_index, s->block_last_index, sizeof(int)*6); @@ -203,7 +203,7 @@ static inline int decide_ac_pred(MpegEncContext * s, int16_t block[6][64], const */ void ff_clean_mpeg4_qscales(MpegEncContext *s){ int i; - int8_t * const qscale_table = s->current_picture.f.qscale_table; + int8_t * const qscale_table = s->current_picture.qscale_table; ff_clean_h263_qscales(s); @@ -499,7 +499,7 @@ void ff_mpeg4_encode_mb(MpegEncContext * s, assert(mb_type>=0); /* nothing to do if this MB was skipped in the next P Frame */ - if (s->next_picture.f.mbskip_table[s->mb_y * s->mb_stride + s->mb_x]) { //FIXME avoid DCT & ... + if (s->next_picture.mbskip_table[s->mb_y * s->mb_stride + s->mb_x]) { //FIXME avoid DCT & ... s->skip_count++; s->mv[0][0][0]= s->mv[0][0][1]= @@ -643,7 +643,7 @@ void ff_mpeg4_encode_mb(MpegEncContext * s, break; b_pic = pic->f.data[0] + offset; - if (pic->f.type != FF_BUFFER_TYPE_SHARED) + if (!pic->shared) b_pic+= INPLACE_OFFSET; diff= s->dsp.sad[0](NULL, p_pic, b_pic, s->linesize, 16); if(diff>s->qscale*70){ //FIXME check that 70 is optimal @@ -747,8 +747,8 @@ void ff_mpeg4_encode_mb(MpegEncContext * s, /* motion vectors: 8x8 mode*/ ff_h263_pred_motion(s, i, 0, &pred_x, &pred_y); - ff_h263_encode_motion_vector(s, s->current_picture.f.motion_val[0][ s->block_index[i] ][0] - pred_x, - s->current_picture.f.motion_val[0][ s->block_index[i] ][1] - pred_y, s->f_code); + ff_h263_encode_motion_vector(s, s->current_picture.motion_val[0][ s->block_index[i] ][0] - pred_x, + s->current_picture.motion_val[0][ s->block_index[i] ][1] - pred_y, s->f_code); } } diff --git a/libavcodec/mpegaudiodec.c b/libavcodec/mpegaudiodec.c index 721f0965a7..e3e19422a4 100644 --- a/libavcodec/mpegaudiodec.c +++ b/libavcodec/mpegaudiodec.c @@ -1611,7 +1611,7 @@ static int mp_decode_frame(MPADecodeContext *s, OUT_INT **samples, if (!samples) { av_assert0(s->frame != NULL); s->frame->nb_samples = s->avctx->frame_size; - if ((ret = ff_get_buffer(s->avctx, s->frame)) < 0) { + if ((ret = ff_get_buffer(s->avctx, s->frame, 0)) < 0) { av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } @@ -1907,7 +1907,7 @@ static int decode_frame_mp3on4(AVCodecContext *avctx, void *data, /* get output buffer */ frame->nb_samples = MPA_FRAME_SIZE; - if ((ret = ff_get_buffer(avctx, frame)) < 0) { + if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } diff --git a/libavcodec/mpegvideo.c b/libavcodec/mpegvideo.c index bee32d5452..b48640f8fc 100644 --- a/libavcodec/mpegvideo.c +++ b/libavcodec/mpegvideo.c @@ -27,6 +27,7 @@ * The simplest mpeg encoder (well, it was the simplest!). */ +#include "libavutil/avassert.h" #include "libavutil/imgutils.h" #include "avcodec.h" #include "dsputil.h" @@ -233,28 +234,6 @@ av_cold int ff_dct_common_init(MpegEncContext *s) return 0; } -void ff_copy_picture(Picture *dst, Picture *src) -{ - *dst = *src; - dst->f.type = FF_BUFFER_TYPE_COPY; -} - -/** - * Release a frame buffer - */ -static void free_frame_buffer(MpegEncContext *s, Picture *pic) -{ - /* WM Image / Screen codecs allocate internal buffers with different - * dimensions / colorspaces; ignore user-defined callbacks for these. */ - if (s->codec_id != AV_CODEC_ID_WMV3IMAGE && - s->codec_id != AV_CODEC_ID_VC1IMAGE && - s->codec_id != AV_CODEC_ID_MSS2) - ff_thread_release_buffer(s->avctx, &pic->f); - else - avcodec_default_release_buffer(s->avctx, &pic->f); - av_freep(&pic->hwaccel_picture_private); -} - int ff_mpv_frame_size_alloc(MpegEncContext *s, int linesize) { int alloc_size = FFALIGN(FFABS(linesize) + 32, 32); @@ -298,16 +277,22 @@ static int alloc_frame_buffer(MpegEncContext *s, Picture *pic) } } + pic->tf.f = &pic->f; if (s->codec_id != AV_CODEC_ID_WMV3IMAGE && s->codec_id != AV_CODEC_ID_VC1IMAGE && s->codec_id != AV_CODEC_ID_MSS2) - r = ff_thread_get_buffer(s->avctx, &pic->f); - else - r = avcodec_default_get_buffer(s->avctx, &pic->f); + r = ff_thread_get_buffer(s->avctx, &pic->tf, + pic->reference ? AV_GET_BUFFER_FLAG_REF : 0); + else { + pic->f.width = s->avctx->width; + pic->f.height = s->avctx->height; + pic->f.format = s->avctx->pix_fmt; + r = avcodec_default_get_buffer2(s->avctx, &pic->f, 0); + } - if (r < 0 || !pic->f.type || !pic->f.data[0]) { - av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed (%d %d %p)\n", - r, pic->f.type, pic->f.data[0]); + if (r < 0 || !pic->f.data[0]) { + av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed (%d %p)\n", + r, pic->f.data[0]); av_freep(&pic->hwaccel_picture_private); return -1; } @@ -316,14 +301,14 @@ static int alloc_frame_buffer(MpegEncContext *s, Picture *pic) s->uvlinesize != pic->f.linesize[1])) { av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed (stride changed)\n"); - free_frame_buffer(s, pic); + ff_mpeg_unref_picture(s, pic); return -1; } if (pic->f.linesize[1] != pic->f.linesize[2]) { av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed (uv stride mismatch)\n"); - free_frame_buffer(s, pic); + ff_mpeg_unref_picture(s, pic); return -1; } @@ -331,33 +316,105 @@ static int alloc_frame_buffer(MpegEncContext *s, Picture *pic) (ret = ff_mpv_frame_size_alloc(s, pic->f.linesize[0])) < 0) { av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed to allocate context scratch buffers.\n"); - free_frame_buffer(s, pic); + ff_mpeg_unref_picture(s, pic); return ret; } return 0; } +static void free_picture_tables(Picture *pic) +{ + int i; + + av_buffer_unref(&pic->mb_var_buf); + av_buffer_unref(&pic->mc_mb_var_buf); + av_buffer_unref(&pic->mb_mean_buf); + av_buffer_unref(&pic->mbskip_table_buf); + av_buffer_unref(&pic->qscale_table_buf); + av_buffer_unref(&pic->mb_type_buf); + + for (i = 0; i < 2; i++) { + av_buffer_unref(&pic->motion_val_buf[i]); + av_buffer_unref(&pic->ref_index_buf[i]); + } +} + +static int alloc_picture_tables(MpegEncContext *s, Picture *pic) +{ + const int big_mb_num = s->mb_stride * (s->mb_height + 1) + 1; + const int mb_array_size = s->mb_stride * s->mb_height; + const int b8_array_size = s->b8_stride * s->mb_height * 2; + int i; + + + pic->mbskip_table_buf = av_buffer_allocz(mb_array_size + 2); + pic->qscale_table_buf = av_buffer_allocz(big_mb_num + s->mb_stride); + pic->mb_type_buf = av_buffer_allocz((big_mb_num + s->mb_stride) * + sizeof(uint32_t)); + if (!pic->mbskip_table_buf || !pic->qscale_table_buf || !pic->mb_type_buf) + return AVERROR(ENOMEM); + + if (s->encoding) { + pic->mb_var_buf = av_buffer_allocz(mb_array_size * sizeof(int16_t)); + pic->mc_mb_var_buf = av_buffer_allocz(mb_array_size * sizeof(int16_t)); + pic->mb_mean_buf = av_buffer_allocz(mb_array_size); + if (!pic->mb_var_buf || !pic->mc_mb_var_buf || !pic->mb_mean_buf) + return AVERROR(ENOMEM); + } + + if (s->out_format == FMT_H263 || s->encoding || + (s->avctx->debug & FF_DEBUG_MV) || s->avctx->debug_mv) { + int mv_size = 2 * (b8_array_size + 4) * sizeof(int16_t); + int ref_index_size = 4 * mb_array_size; + + for (i = 0; mv_size && i < 2; i++) { + pic->motion_val_buf[i] = av_buffer_allocz(mv_size); + pic->ref_index_buf[i] = av_buffer_allocz(ref_index_size); + if (!pic->motion_val_buf[i] || !pic->ref_index_buf[i]) + return AVERROR(ENOMEM); + } + } + + return 0; +} + +static int make_tables_writable(Picture *pic) +{ + int ret, i; +#define MAKE_WRITABLE(table) \ +do {\ + if (pic->table &&\ + (ret = av_buffer_make_writable(&pic->table)) < 0)\ + return ret;\ +} while (0) + + MAKE_WRITABLE(mb_var_buf); + MAKE_WRITABLE(mc_mb_var_buf); + MAKE_WRITABLE(mb_mean_buf); + MAKE_WRITABLE(mbskip_table_buf); + MAKE_WRITABLE(qscale_table_buf); + MAKE_WRITABLE(mb_type_buf); + + for (i = 0; i < 2; i++) { + MAKE_WRITABLE(motion_val_buf[i]); + MAKE_WRITABLE(ref_index_buf[i]); + } + + return 0; +} + /** * Allocate a Picture. * The pixels are allocated/set by calling get_buffer() if shared = 0 */ int ff_alloc_picture(MpegEncContext *s, Picture *pic, int shared) { - const int big_mb_num = s->mb_stride * (s->mb_height + 1) + 1; - - // the + 1 is needed so memset(,,stride*height) does not sig11 - - const int mb_array_size = s->mb_stride * s->mb_height; - const int b8_array_size = s->b8_stride * s->mb_height * 2; - const int b4_array_size = s->b4_stride * s->mb_height * 4; - int i; - int r = -1; + int i, ret; if (shared) { assert(pic->f.data[0]); - assert(pic->f.type == 0 || pic->f.type == FF_BUFFER_TYPE_SHARED); - pic->f.type = FF_BUFFER_TYPE_SHARED; + pic->shared = 1; } else { assert(!pic->f.data[0]); @@ -368,101 +425,138 @@ int ff_alloc_picture(MpegEncContext *s, Picture *pic, int shared) s->uvlinesize = pic->f.linesize[1]; } - if (pic->f.qscale_table == NULL) { - if (s->encoding) { - FF_ALLOCZ_OR_GOTO(s->avctx, pic->mb_var, - mb_array_size * sizeof(int16_t), fail) - FF_ALLOCZ_OR_GOTO(s->avctx, pic->mc_mb_var, - mb_array_size * sizeof(int16_t), fail) - FF_ALLOCZ_OR_GOTO(s->avctx, pic->mb_mean, - mb_array_size * sizeof(int8_t ), fail) - } + if (!pic->qscale_table_buf) + ret = alloc_picture_tables(s, pic); + else + ret = make_tables_writable(pic); + if (ret < 0) + goto fail; - FF_ALLOCZ_OR_GOTO(s->avctx, pic->f.mbskip_table, - mb_array_size * sizeof(uint8_t) + 2, fail)// the + 2 is for the slice end check - FF_ALLOCZ_OR_GOTO(s->avctx, pic->qscale_table_base, - (big_mb_num + s->mb_stride) * sizeof(uint8_t), - fail) - FF_ALLOCZ_OR_GOTO(s->avctx, pic->mb_type_base, - (big_mb_num + s->mb_stride) * sizeof(uint32_t), - fail) - pic->f.mb_type = pic->mb_type_base + 2 * s->mb_stride + 1; - pic->f.qscale_table = pic->qscale_table_base + 2 * s->mb_stride + 1; - if (s->out_format == FMT_H264) { - for (i = 0; i < 2; i++) { - FF_ALLOCZ_OR_GOTO(s->avctx, pic->motion_val_base[i], - 2 * (b4_array_size + 4) * sizeof(int16_t), - fail) - pic->f.motion_val[i] = pic->motion_val_base[i] + 4; - FF_ALLOCZ_OR_GOTO(s->avctx, pic->f.ref_index[i], - 4 * mb_array_size * sizeof(uint8_t), fail) - } - pic->f.motion_subsample_log2 = 2; - } else if (s->out_format == FMT_H263 || s->encoding || - (s->avctx->debug & FF_DEBUG_MV) || s->avctx->debug_mv) { - for (i = 0; i < 2; i++) { - FF_ALLOCZ_OR_GOTO(s->avctx, pic->motion_val_base[i], - 2 * (b8_array_size + 4) * sizeof(int16_t), - fail) - pic->f.motion_val[i] = pic->motion_val_base[i] + 4; - FF_ALLOCZ_OR_GOTO(s->avctx, pic->f.ref_index[i], - 4 * mb_array_size * sizeof(uint8_t), fail) - } - pic->f.motion_subsample_log2 = 3; - } - if (s->avctx->debug&FF_DEBUG_DCT_COEFF) { - FF_ALLOCZ_OR_GOTO(s->avctx, pic->f.dct_coeff, - 64 * mb_array_size * sizeof(int16_t) * 6, fail) - } - pic->f.qstride = s->mb_stride; - FF_ALLOCZ_OR_GOTO(s->avctx, pic->f.pan_scan, - 1 * sizeof(AVPanScan), fail) + if (s->encoding) { + pic->mb_var = (uint16_t*)pic->mb_var_buf->data; + pic->mc_mb_var = (uint16_t*)pic->mc_mb_var_buf->data; + pic->mb_mean = pic->mb_mean_buf->data; } - pic->owner2 = s; + pic->mbskip_table = pic->mbskip_table_buf->data; + pic->qscale_table = pic->qscale_table_buf->data + 2 * s->mb_stride + 1; + pic->mb_type = (uint32_t*)pic->mb_type_buf->data + 2 * s->mb_stride + 1; + + if (pic->motion_val_buf[0]) { + for (i = 0; i < 2; i++) { + pic->motion_val[i] = (int16_t (*)[2])pic->motion_val_buf[i]->data + 4; + pic->ref_index[i] = pic->ref_index_buf[i]->data; + } + } return 0; -fail: // for the FF_ALLOCZ_OR_GOTO macro - if (r >= 0) - free_frame_buffer(s, pic); - return -1; +fail: + av_log(s->avctx, AV_LOG_ERROR, "Error allocating a picture.\n"); + ff_mpeg_unref_picture(s, pic); + free_picture_tables(pic); + return AVERROR(ENOMEM); } /** * Deallocate a picture. */ -static void free_picture(MpegEncContext *s, Picture *pic) +void ff_mpeg_unref_picture(MpegEncContext *s, Picture *pic) { - int i; + int off = offsetof(Picture, mb_mean) + sizeof(pic->mb_mean); - if (pic->f.data[0] && pic->f.type != FF_BUFFER_TYPE_SHARED) { - free_frame_buffer(s, pic); - } + pic->tf.f = &pic->f; + /* WM Image / Screen codecs allocate internal buffers with different + * dimensions / colorspaces; ignore user-defined callbacks for these. */ + if (s->codec_id != AV_CODEC_ID_WMV3IMAGE && + s->codec_id != AV_CODEC_ID_VC1IMAGE && + s->codec_id != AV_CODEC_ID_MSS2) + ff_thread_release_buffer(s->avctx, &pic->tf); + else + av_frame_unref(&pic->f); - av_freep(&pic->mb_var); - av_freep(&pic->mc_mb_var); - av_freep(&pic->mb_mean); - av_freep(&pic->f.mbskip_table); - av_freep(&pic->qscale_table_base); - pic->f.qscale_table = NULL; - av_freep(&pic->mb_type_base); - pic->f.mb_type = NULL; - av_freep(&pic->f.dct_coeff); - av_freep(&pic->f.pan_scan); - pic->f.mb_type = NULL; + av_buffer_unref(&pic->hwaccel_priv_buf); + + memset((uint8_t*)pic + off, 0, sizeof(*pic) - off); +} + +static int update_picture_tables(Picture *dst, Picture *src) +{ + int i; + +#define UPDATE_TABLE(table)\ +do {\ + if (src->table &&\ + (!dst->table || dst->table->buffer != src->table->buffer)) {\ + av_buffer_unref(&dst->table);\ + dst->table = av_buffer_ref(src->table);\ + if (!dst->table) {\ + free_picture_tables(dst);\ + return AVERROR(ENOMEM);\ + }\ + }\ +} while (0) + + UPDATE_TABLE(mb_var_buf); + UPDATE_TABLE(mc_mb_var_buf); + UPDATE_TABLE(mb_mean_buf); + UPDATE_TABLE(mbskip_table_buf); + UPDATE_TABLE(qscale_table_buf); + UPDATE_TABLE(mb_type_buf); for (i = 0; i < 2; i++) { - av_freep(&pic->motion_val_base[i]); - av_freep(&pic->f.ref_index[i]); - pic->f.motion_val[i] = NULL; + UPDATE_TABLE(motion_val_buf[i]); + UPDATE_TABLE(ref_index_buf[i]); } - if (pic->f.type == FF_BUFFER_TYPE_SHARED) { - for (i = 0; i < 4; i++) { - pic->f.base[i] = - pic->f.data[i] = NULL; - } - pic->f.type = 0; + dst->mb_var = src->mb_var; + dst->mc_mb_var = src->mc_mb_var; + dst->mb_mean = src->mb_mean; + dst->mbskip_table = src->mbskip_table; + dst->qscale_table = src->qscale_table; + dst->mb_type = src->mb_type; + for (i = 0; i < 2; i++) { + dst->motion_val[i] = src->motion_val[i]; + dst->ref_index[i] = src->ref_index[i]; } + + return 0; +} + +int ff_mpeg_ref_picture(MpegEncContext *s, Picture *dst, Picture *src) +{ + int ret; + + av_assert0(!dst->f.buf[0]); + av_assert0(src->f.buf[0]); + + src->tf.f = &src->f; + dst->tf.f = &dst->f; + ret = ff_thread_ref_frame(&dst->tf, &src->tf); + if (ret < 0) + goto fail; + + ret = update_picture_tables(dst, src); + if (ret < 0) + goto fail; + + if (src->hwaccel_picture_private) { + dst->hwaccel_priv_buf = av_buffer_ref(src->hwaccel_priv_buf); + if (!dst->hwaccel_priv_buf) + goto fail; + dst->hwaccel_picture_private = dst->hwaccel_priv_buf->data; + } + + dst->field_picture = src->field_picture; + dst->mb_var_sum = src->mb_var_sum; + dst->mc_mb_var_sum = src->mc_mb_var_sum; + dst->b_frame_score = src->b_frame_score; + dst->needs_realloc = src->needs_realloc; + dst->reference = src->reference; + dst->shared = src->shared; + + return 0; +fail: + ff_mpeg_unref_picture(s, dst); + return ret; } static int init_duplicate_context(MpegEncContext *s) @@ -583,7 +677,7 @@ int ff_update_duplicate_context(MpegEncContext *dst, MpegEncContext *src) int ff_mpeg_update_thread_context(AVCodecContext *dst, const AVCodecContext *src) { - int i; + int i, ret; MpegEncContext *s = dst->priv_data, *s1 = src->priv_data; if (dst == src || !s1->context_initialized) @@ -595,8 +689,6 @@ int ff_mpeg_update_thread_context(AVCodecContext *dst, memcpy(s, s1, sizeof(MpegEncContext)); s->avctx = dst; - s->picture_range_start += MAX_PICTURE_COUNT; - s->picture_range_end += MAX_PICTURE_COUNT; s->bitstream_buffer = NULL; s->bitstream_buffer_size = s->allocated_bitstream_buffer_size = 0; @@ -621,13 +713,27 @@ int ff_mpeg_update_thread_context(AVCodecContext *dst, s->picture_number = s1->picture_number; s->input_picture_number = s1->input_picture_number; - memcpy(s->picture, s1->picture, s1->picture_count * sizeof(Picture)); - memcpy(&s->last_picture, &s1->last_picture, - (char *) &s1->last_picture_ptr - (char *) &s1->last_picture); + for (i = 0; i < MAX_PICTURE_COUNT; i++) { + ff_mpeg_unref_picture(s, &s->picture[i]); + if (s1->picture[i].f.data[0] && + (ret = ff_mpeg_ref_picture(s, &s->picture[i], &s1->picture[i])) < 0) + return ret; + } - // reset s->picture[].f.extended_data to s->picture[].f.data - for (i = 0; i < s->picture_count; i++) - s->picture[i].f.extended_data = s->picture[i].f.data; +#define UPDATE_PICTURE(pic)\ +do {\ + ff_mpeg_unref_picture(s, &s->pic);\ + if (s1->pic.f.data[0])\ + ret = ff_mpeg_ref_picture(s, &s->pic, &s1->pic);\ + else\ + ret = update_picture_tables(&s->pic, &s1->pic);\ + if (ret < 0)\ + return ret;\ +} while (0) + + UPDATE_PICTURE(current_picture); + UPDATE_PICTURE(last_picture); + UPDATE_PICTURE(next_picture); s->last_picture_ptr = REBASE_PICTURE(s1->last_picture_ptr, s, s1); s->current_picture_ptr = REBASE_PICTURE(s1->current_picture_ptr, s, s1); @@ -717,9 +823,6 @@ void ff_MPV_common_defaults(MpegEncContext *s) s->f_code = 1; s->b_code = 1; - s->picture_range_start = 0; - s->picture_range_end = MAX_PICTURE_COUNT; - s->slice_context_count = 1; } @@ -1006,12 +1109,17 @@ av_cold int ff_MPV_common_init(MpegEncContext *s) } } - s->picture_count = MAX_PICTURE_COUNT * FFMAX(1, s->avctx->thread_count); FF_ALLOCZ_OR_GOTO(s->avctx, s->picture, - s->picture_count * sizeof(Picture), fail); - for (i = 0; i < s->picture_count; i++) { + MAX_PICTURE_COUNT * sizeof(Picture), fail); + for (i = 0; i < MAX_PICTURE_COUNT; i++) { avcodec_get_frame_defaults(&s->picture[i].f); } + memset(&s->next_picture, 0, sizeof(s->next_picture)); + memset(&s->last_picture, 0, sizeof(s->last_picture)); + memset(&s->current_picture, 0, sizeof(s->current_picture)); + avcodec_get_frame_defaults(&s->next_picture.f); + avcodec_get_frame_defaults(&s->last_picture.f); + avcodec_get_frame_defaults(&s->current_picture.f); if (s->width && s->height) { if (init_context_frame(s)) @@ -1125,10 +1233,11 @@ int ff_MPV_common_frame_size_change(MpegEncContext *s) } else free_duplicate_context(s); - free_context_frame(s); + if ((err = free_context_frame(s)) < 0) + return err; if (s->picture) - for (i = 0; i < s->picture_count; i++) { + for (i = 0; i < MAX_PICTURE_COUNT; i++) { s->picture[i].needs_realloc = 1; } @@ -1214,18 +1323,24 @@ void ff_MPV_common_end(MpegEncContext *s) av_freep(&s->reordered_input_picture); av_freep(&s->dct_offset); - if (s->picture && !s->avctx->internal->is_copy) { - for (i = 0; i < s->picture_count; i++) { - free_picture(s, &s->picture[i]); + if (s->picture) { + for (i = 0; i < MAX_PICTURE_COUNT; i++) { + free_picture_tables(&s->picture[i]); + ff_mpeg_unref_picture(s, &s->picture[i]); } } av_freep(&s->picture); + free_picture_tables(&s->last_picture); + ff_mpeg_unref_picture(s, &s->last_picture); + free_picture_tables(&s->current_picture); + ff_mpeg_unref_picture(s, &s->current_picture); + free_picture_tables(&s->next_picture); + ff_mpeg_unref_picture(s, &s->next_picture); + free_picture_tables(&s->new_picture); + ff_mpeg_unref_picture(s, &s->new_picture); free_context_frame(s); - if (!(s->avctx->active_thread_type & FF_THREAD_FRAME)) - avcodec_default_free_buffers(s->avctx); - s->context_initialized = 0; s->last_picture_ptr = s->next_picture_ptr = @@ -1330,12 +1445,10 @@ void ff_release_unused_pictures(MpegEncContext*s, int remove_current) int i; /* release non reference frames */ - for (i = 0; i < s->picture_count; i++) { - if (s->picture[i].f.data[0] && !s->picture[i].f.reference && - (!s->picture[i].owner2 || s->picture[i].owner2 == s) && - (remove_current || &s->picture[i] != s->current_picture_ptr) - /* && s->picture[i].type!= FF_BUFFER_TYPE_SHARED */) { - free_frame_buffer(s, &s->picture[i]); + for (i = 0; i < MAX_PICTURE_COUNT; i++) { + if (!s->picture[i].reference && + (remove_current || &s->picture[i] != s->current_picture_ptr)) { + ff_mpeg_unref_picture(s, &s->picture[i]); } } } @@ -1344,9 +1457,8 @@ static inline int pic_is_unused(MpegEncContext *s, Picture *pic) { if (pic->f.data[0] == NULL) return 1; - if (pic->needs_realloc && !(pic->f.reference & DELAYED_PIC_REF)) - if (!pic->owner2 || pic->owner2 == s) - return 1; + if (pic->needs_realloc && !(pic->reference & DELAYED_PIC_REF)) + return 1; return 0; } @@ -1355,16 +1467,12 @@ static int find_unused_picture(MpegEncContext *s, int shared) int i; if (shared) { - for (i = s->picture_range_start; i < s->picture_range_end; i++) { - if (s->picture[i].f.data[0] == NULL && s->picture[i].f.type == 0) + for (i = 0; i < MAX_PICTURE_COUNT; i++) { + if (s->picture[i].f.data[0] == NULL) return i; } } else { - for (i = s->picture_range_start; i < s->picture_range_end; i++) { - if (pic_is_unused(s, &s->picture[i]) && s->picture[i].f.type != 0) - return i; // FIXME - } - for (i = s->picture_range_start; i < s->picture_range_end; i++) { + for (i = 0; i < MAX_PICTURE_COUNT; i++) { if (pic_is_unused(s, &s->picture[i])) return i; } @@ -1377,10 +1485,11 @@ int ff_find_unused_picture(MpegEncContext *s, int shared) { int ret = find_unused_picture(s, shared); - if (ret >= 0 && ret < s->picture_range_end) { + if (ret >= 0 && ret < MAX_PICTURE_COUNT) { if (s->picture[ret].needs_realloc) { s->picture[ret].needs_realloc = 0; - free_picture(s, &s->picture[ret]); + free_picture_tables(&s->picture[ret]); + ff_mpeg_unref_picture(s, &s->picture[ret]); avcodec_get_frame_defaults(&s->picture[ret].f); } } @@ -1414,7 +1523,7 @@ static void update_noise_reduction(MpegEncContext *s) */ int ff_MPV_frame_start(MpegEncContext *s, AVCodecContext *avctx) { - int i; + int i, ret; Picture *pic; s->mb_skipped = 0; @@ -1423,22 +1532,20 @@ int ff_MPV_frame_start(MpegEncContext *s, AVCodecContext *avctx) if (s->pict_type != AV_PICTURE_TYPE_B && s->last_picture_ptr && s->last_picture_ptr != s->next_picture_ptr && s->last_picture_ptr->f.data[0]) { - if (s->last_picture_ptr->owner2 == s) - free_frame_buffer(s, s->last_picture_ptr); + ff_mpeg_unref_picture(s, s->last_picture_ptr); } /* release forgotten pictures */ /* if (mpeg124/h263) */ if (!s->encoding) { - for (i = 0; i < s->picture_count; i++) { - if (s->picture[i].owner2 == s && s->picture[i].f.data[0] && - &s->picture[i] != s->last_picture_ptr && + for (i = 0; i < MAX_PICTURE_COUNT; i++) { + if (&s->picture[i] != s->last_picture_ptr && &s->picture[i] != s->next_picture_ptr && - s->picture[i].f.reference && !s->picture[i].needs_realloc) { + s->picture[i].reference && !s->picture[i].needs_realloc) { if (!(avctx->active_thread_type & FF_THREAD_FRAME)) av_log(avctx, AV_LOG_ERROR, "releasing zombie picture\n"); - free_frame_buffer(s, &s->picture[i]); + ff_mpeg_unref_picture(s, &s->picture[i]); } } } @@ -1461,12 +1568,12 @@ int ff_MPV_frame_start(MpegEncContext *s, AVCodecContext *avctx) pic = &s->picture[i]; } - pic->f.reference = 0; + pic->reference = 0; if (!s->droppable) { if (s->codec_id == AV_CODEC_ID_H264) - pic->f.reference = s->picture_structure; + pic->reference = s->picture_structure; else if (s->pict_type != AV_PICTURE_TYPE_B) - pic->f.reference = 3; + pic->reference = 3; } pic->f.coded_picture_number = s->coded_picture_number++; @@ -1493,9 +1600,12 @@ int ff_MPV_frame_start(MpegEncContext *s, AVCodecContext *avctx) // s->current_picture_ptr->quality = s->new_picture_ptr->quality; s->current_picture_ptr->f.key_frame = s->pict_type == AV_PICTURE_TYPE_I; - ff_copy_picture(&s->current_picture, s->current_picture_ptr); + ff_mpeg_unref_picture(s, &s->current_picture); + if ((ret = ff_mpeg_ref_picture(s, &s->current_picture, + s->current_picture_ptr)) < 0) + return ret; - if (s->pict_type != AV_PICTURE_TYPE_B) { + if (s->codec_id != AV_CODEC_ID_H264 && s->pict_type != AV_PICTURE_TYPE_B) { s->last_picture_ptr = s->next_picture_ptr; if (!s->droppable) s->next_picture_ptr = s->current_picture_ptr; @@ -1543,9 +1653,8 @@ int ff_MPV_frame_start(MpegEncContext *s, AVCodecContext *avctx) (avctx->height >> v_chroma_shift) * s->last_picture_ptr->f.linesize[2]); - ff_thread_report_progress(&s->last_picture_ptr->f, INT_MAX, 0); - ff_thread_report_progress(&s->last_picture_ptr->f, INT_MAX, 1); - s->last_picture_ptr->f.reference = 3; + ff_thread_report_progress(&s->last_picture_ptr->tf, INT_MAX, 0); + ff_thread_report_progress(&s->last_picture_ptr->tf, INT_MAX, 1); } if ((s->next_picture_ptr == NULL || s->next_picture_ptr->f.data[0] == NULL) && @@ -1561,27 +1670,31 @@ int ff_MPV_frame_start(MpegEncContext *s, AVCodecContext *avctx) s->next_picture_ptr = NULL; return -1; } - ff_thread_report_progress(&s->next_picture_ptr->f, INT_MAX, 0); - ff_thread_report_progress(&s->next_picture_ptr->f, INT_MAX, 1); - s->next_picture_ptr->f.reference = 3; + ff_thread_report_progress(&s->next_picture_ptr->tf, INT_MAX, 0); + ff_thread_report_progress(&s->next_picture_ptr->tf, INT_MAX, 1); } } - if (s->last_picture_ptr) - ff_copy_picture(&s->last_picture, s->last_picture_ptr); - if (s->next_picture_ptr) - ff_copy_picture(&s->next_picture, s->next_picture_ptr); + if (s->codec_id != AV_CODEC_ID_H264) { + if (s->last_picture_ptr) { + ff_mpeg_unref_picture(s, &s->last_picture); + if (s->last_picture_ptr->f.data[0] && + (ret = ff_mpeg_ref_picture(s, &s->last_picture, + s->last_picture_ptr)) < 0) + return ret; + } + if (s->next_picture_ptr) { + ff_mpeg_unref_picture(s, &s->next_picture); + if (s->next_picture_ptr->f.data[0] && + (ret = ff_mpeg_ref_picture(s, &s->next_picture, + s->next_picture_ptr)) < 0) + return ret; + } - if (HAVE_THREADS && (avctx->active_thread_type & FF_THREAD_FRAME)) { - if (s->next_picture_ptr) - s->next_picture_ptr->owner2 = s; - if (s->last_picture_ptr) - s->last_picture_ptr->owner2 = s; + assert(s->pict_type == AV_PICTURE_TYPE_I || (s->last_picture_ptr && + s->last_picture_ptr->f.data[0])); } - assert(s->pict_type == AV_PICTURE_TYPE_I || (s->last_picture_ptr && - s->last_picture_ptr->f.data[0])); - if (s->picture_structure!= PICT_FRAME && s->out_format != FMT_H264) { int i; for (i = 0; i < 4; i++) { @@ -1635,7 +1748,7 @@ void ff_MPV_frame_end(MpegEncContext *s) !s->avctx->hwaccel && !(s->avctx->codec->capabilities & CODEC_CAP_HWACCEL_VDPAU) && s->unrestricted_mv && - s->current_picture.f.reference && + s->current_picture.reference && !s->intra_only && !(s->flags & CODEC_FLAG_EMU_EDGE)) { const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(s->avctx->pix_fmt); @@ -1675,11 +1788,9 @@ void ff_MPV_frame_end(MpegEncContext *s) if (s->encoding) { /* release non-reference frames */ - for (i = 0; i < s->picture_count; i++) { - if (s->picture[i].f.data[0] && !s->picture[i].f.reference - /* && s->picture[i].type != FF_BUFFER_TYPE_SHARED */) { - free_frame_buffer(s, &s->picture[i]); - } + for (i = 0; i < MAX_PICTURE_COUNT; i++) { + if (!s->picture[i].reference) + ff_mpeg_unref_picture(s, &s->picture[i]); } } // clear copies, to avoid confusion @@ -1690,9 +1801,8 @@ void ff_MPV_frame_end(MpegEncContext *s) #endif s->avctx->coded_frame = &s->current_picture_ptr->f; - if (s->codec_id != AV_CODEC_ID_H264 && s->current_picture.f.reference) { - ff_thread_report_progress(&s->current_picture_ptr->f, INT_MAX, 0); - } + if (s->codec_id != AV_CODEC_ID_H264 && s->current_picture.reference) + ff_thread_report_progress(&s->current_picture_ptr->tf, INT_MAX, 0); } /** @@ -1786,10 +1896,12 @@ static void draw_arrow(uint8_t *buf, int sx, int sy, int ex, /** * Print debugging info for the given picture. */ -void ff_print_debug_info(MpegEncContext *s, AVFrame *pict) +void ff_print_debug_info(MpegEncContext *s, Picture *p) { - if (s->avctx->hwaccel || !pict || !pict->mb_type) + AVFrame *pict; + if (s->avctx->hwaccel || !p || !p->mb_type) return; + pict = &p->f; if (s->avctx->debug & (FF_DEBUG_SKIP | FF_DEBUG_QP | FF_DEBUG_MB_TYPE)) { int x,y; @@ -1825,10 +1937,10 @@ void ff_print_debug_info(MpegEncContext *s, AVFrame *pict) } if (s->avctx->debug & FF_DEBUG_QP) { av_log(s->avctx, AV_LOG_DEBUG, "%2d", - pict->qscale_table[x + y * s->mb_stride]); + p->qscale_table[x + y * s->mb_stride]); } if (s->avctx->debug & FF_DEBUG_MB_TYPE) { - int mb_type = pict->mb_type[x + y * s->mb_stride]; + int mb_type = p->mb_type[x + y * s->mb_stride]; // Type & MV direction if (IS_PCM(mb_type)) av_log(s->avctx, AV_LOG_DEBUG, "P"); @@ -1902,7 +2014,6 @@ void ff_print_debug_info(MpegEncContext *s, AVFrame *pict) pict->linesize[i] * height >> v_chroma_shift); pict->data[i] = s->visualization_buffer[i]; } - pict->type = FF_BUFFER_TYPE_COPY; ptr = pict->data[0]; block_height = 16 >> v_chroma_shift; @@ -1910,7 +2021,7 @@ void ff_print_debug_info(MpegEncContext *s, AVFrame *pict) int mb_x; for (mb_x = 0; mb_x < s->mb_width; mb_x++) { const int mb_index = mb_x + mb_y * s->mb_stride; - if ((s->avctx->debug_mv) && pict->motion_val) { + if ((s->avctx->debug_mv) && p->motion_val) { int type; for (type = 0; type < 3; type++) { int direction = 0; @@ -1934,46 +2045,46 @@ void ff_print_debug_info(MpegEncContext *s, AVFrame *pict) direction = 1; break; } - if (!USES_LIST(pict->mb_type[mb_index], direction)) + if (!USES_LIST(p->mb_type[mb_index], direction)) continue; - if (IS_8X8(pict->mb_type[mb_index])) { + if (IS_8X8(p->mb_type[mb_index])) { int i; for (i = 0; i < 4; i++) { int sx = mb_x * 16 + 4 + 8 * (i & 1); int sy = mb_y * 16 + 4 + 8 * (i >> 1); int xy = (mb_x * 2 + (i & 1) + (mb_y * 2 + (i >> 1)) * mv_stride) << (mv_sample_log2 - 1); - int mx = (pict->motion_val[direction][xy][0] >> shift) + sx; - int my = (pict->motion_val[direction][xy][1] >> shift) + sy; + int mx = (p->motion_val[direction][xy][0] >> shift) + sx; + int my = (p->motion_val[direction][xy][1] >> shift) + sy; draw_arrow(ptr, sx, sy, mx, my, width, height, s->linesize, 100); } - } else if (IS_16X8(pict->mb_type[mb_index])) { + } else if (IS_16X8(p->mb_type[mb_index])) { int i; for (i = 0; i < 2; i++) { int sx = mb_x * 16 + 8; int sy = mb_y * 16 + 4 + 8 * i; int xy = (mb_x * 2 + (mb_y * 2 + i) * mv_stride) << (mv_sample_log2 - 1); - int mx = (pict->motion_val[direction][xy][0] >> shift); - int my = (pict->motion_val[direction][xy][1] >> shift); + int mx = (p->motion_val[direction][xy][0] >> shift); + int my = (p->motion_val[direction][xy][1] >> shift); - if (IS_INTERLACED(pict->mb_type[mb_index])) + if (IS_INTERLACED(p->mb_type[mb_index])) my *= 2; draw_arrow(ptr, sx, sy, mx + sx, my + sy, width, height, s->linesize, 100); } - } else if (IS_8X16(pict->mb_type[mb_index])) { + } else if (IS_8X16(p->mb_type[mb_index])) { int i; for (i = 0; i < 2; i++) { int sx = mb_x * 16 + 4 + 8 * i; int sy = mb_y * 16 + 8; int xy = (mb_x * 2 + i + mb_y * 2 * mv_stride) << (mv_sample_log2 - 1); - int mx = pict->motion_val[direction][xy][0] >> shift; - int my = pict->motion_val[direction][xy][1] >> shift; + int mx = p->motion_val[direction][xy][0] >> shift; + int my = p->motion_val[direction][xy][1] >> shift; - if (IS_INTERLACED(pict->mb_type[mb_index])) + if (IS_INTERLACED(p->mb_type[mb_index])) my *= 2; draw_arrow(ptr, sx, sy, mx + sx, my + sy, width, @@ -1983,14 +2094,14 @@ void ff_print_debug_info(MpegEncContext *s, AVFrame *pict) int sx = mb_x * 16 + 8; int sy = mb_y * 16 + 8; int xy = (mb_x + mb_y * mv_stride) << mv_sample_log2; - int mx = pict->motion_val[direction][xy][0] >> shift + sx; - int my = pict->motion_val[direction][xy][1] >> shift + sy; + int mx = p->motion_val[direction][xy][0] >> shift + sx; + int my = p->motion_val[direction][xy][1] >> shift + sy; draw_arrow(ptr, sx, sy, mx, my, width, height, s->linesize, 100); } } } - if ((s->avctx->debug & FF_DEBUG_VIS_QP) && pict->motion_val) { - uint64_t c = (pict->qscale_table[mb_index] * 128 / 31) * + if ((s->avctx->debug & FF_DEBUG_VIS_QP) && p->motion_val) { + uint64_t c = (p->qscale_table[mb_index] * 128 / 31) * 0x0101010101010101ULL; int y; for (y = 0; y < block_height; y++) { @@ -2003,8 +2114,8 @@ void ff_print_debug_info(MpegEncContext *s, AVFrame *pict) } } if ((s->avctx->debug & FF_DEBUG_VIS_MB_TYPE) && - pict->motion_val) { - int mb_type = pict->mb_type[mb_index]; + p->motion_val) { + int mb_type = p->mb_type[mb_index]; uint64_t u,v; int y; #define COLOR(theta, r) \ @@ -2068,7 +2179,7 @@ void ff_print_debug_info(MpegEncContext *s, AVFrame *pict) int xy = (mb_x * 2 + (i & 1) + (mb_y * 2 + (i >> 1)) * mv_stride) << (mv_sample_log2 - 1); // FIXME bidir - int32_t *mv = (int32_t *) &pict->motion_val[0][xy]; + int32_t *mv = (int32_t *) &p->motion_val[0][xy]; if (mv[0] != mv[dm] || mv[dm * mv_stride] != mv[dm * (mv_stride + 1)]) for (y = 0; y < 8; y++) @@ -2209,20 +2320,18 @@ void MPV_decode_mb_internal(MpegEncContext *s, int16_t block[12][64], } if(s->avctx->debug&FF_DEBUG_DCT_COEFF) { - /* save DCT coefficients */ + /* print DCT coefficients */ int i,j; - int16_t *dct = &s->current_picture.f.dct_coeff[mb_xy * 64 * 6]; av_log(s->avctx, AV_LOG_DEBUG, "DCT coeffs of MB at %dx%d:\n", s->mb_x, s->mb_y); for(i=0; i<6; i++){ for(j=0; j<64; j++){ - *dct++ = block[i][s->dsp.idct_permutation[j]]; - av_log(s->avctx, AV_LOG_DEBUG, "%5d", dct[-1]); + av_log(s->avctx, AV_LOG_DEBUG, "%5d", block[i][s->dsp.idct_permutation[j]]); } av_log(s->avctx, AV_LOG_DEBUG, "\n"); } } - s->current_picture.f.qscale_table[mb_xy] = s->qscale; + s->current_picture.qscale_table[mb_xy] = s->qscale; /* update DC predictors for P macroblocks */ if (!s->mb_intra) { @@ -2257,7 +2366,7 @@ void MPV_decode_mb_internal(MpegEncContext *s, int16_t block[12][64], s->mb_skipped= 0; assert(s->pict_type!=AV_PICTURE_TYPE_I); *mbskip_ptr = 1; - } else if(!s->current_picture.f.reference) { + } else if(!s->current_picture.reference) { *mbskip_ptr = 1; } else{ *mbskip_ptr = 0; /* not skipped */ @@ -2284,12 +2393,12 @@ void MPV_decode_mb_internal(MpegEncContext *s, int16_t block[12][64], if(HAVE_THREADS && s->avctx->active_thread_type&FF_THREAD_FRAME) { if (s->mv_dir & MV_DIR_FORWARD) { - ff_thread_await_progress(&s->last_picture_ptr->f, + ff_thread_await_progress(&s->last_picture_ptr->tf, ff_MPV_lowest_referenced_row(s, 0), 0); } if (s->mv_dir & MV_DIR_BACKWARD) { - ff_thread_await_progress(&s->next_picture_ptr->f, + ff_thread_await_progress(&s->next_picture_ptr->tf, ff_MPV_lowest_referenced_row(s, 1), 0); } @@ -2459,7 +2568,7 @@ void ff_draw_horiz_band(AVCodecContext *avctx, DSPContext *dsp, Picture *cur, if (!avctx->hwaccel && !(avctx->codec->capabilities & CODEC_CAP_HWACCEL_VDPAU) && draw_edges && - cur->f.reference && + cur->reference && !(avctx->flags & CODEC_FLAG_EMU_EDGE)) { int *linesize = cur->f.linesize; int sides = 0, edge_h; @@ -2595,12 +2704,8 @@ void ff_mpeg_flush(AVCodecContext *avctx){ if(s==NULL || s->picture==NULL) return; - for(i=0; ipicture_count; i++){ - if (s->picture[i].f.data[0] && - (s->picture[i].f.type == FF_BUFFER_TYPE_INTERNAL || - s->picture[i].f.type == FF_BUFFER_TYPE_USER)) - free_frame_buffer(s, &s->picture[i]); - } + for (i = 0; i < MAX_PICTURE_COUNT; i++) + ff_mpeg_unref_picture(s, &s->picture[i]); s->current_picture_ptr = s->last_picture_ptr = s->next_picture_ptr = NULL; s->mb_x= s->mb_y= 0; @@ -2853,7 +2958,7 @@ void ff_set_qscale(MpegEncContext * s, int qscale) void ff_MPV_report_decode_progress(MpegEncContext *s) { if (s->pict_type != AV_PICTURE_TYPE_B && !s->partitioned_frame && !s->er.error_occurred) - ff_thread_report_progress(&s->current_picture_ptr->f, s->mb_y, 0); + ff_thread_report_progress(&s->current_picture_ptr->tf, s->mb_y, 0); } #if CONFIG_ERROR_RESILIENCE diff --git a/libavcodec/mpegvideo.h b/libavcodec/mpegvideo.h index 532a70a43e..51c7495a04 100644 --- a/libavcodec/mpegvideo.h +++ b/libavcodec/mpegvideo.h @@ -37,6 +37,7 @@ #include "parser.h" #include "mpeg12data.h" #include "rl.h" +#include "thread.h" #include "videodsp.h" #include "libavutil/opt.h" @@ -94,10 +95,38 @@ struct MpegEncContext; */ typedef struct Picture{ struct AVFrame f; + ThreadFrame tf; + + AVBufferRef *qscale_table_buf; + int8_t *qscale_table; + + AVBufferRef *motion_val_buf[2]; + int16_t (*motion_val[2])[2]; + + AVBufferRef *mb_type_buf; + uint32_t *mb_type; + + AVBufferRef *mbskip_table_buf; + uint8_t *mbskip_table; + + AVBufferRef *ref_index_buf[2]; + int8_t *ref_index[2]; + + AVBufferRef *mb_var_buf; + uint16_t *mb_var; ///< Table for MB variances + + AVBufferRef *mc_mb_var_buf; + uint16_t *mc_mb_var; ///< Table for motion compensated MB variances + + AVBufferRef *mb_mean_buf; + uint8_t *mb_mean; ///< Table for MB luminance + + AVBufferRef *hwaccel_priv_buf; + /** + * hardware accelerator private data + */ + void *hwaccel_picture_private; - int8_t *qscale_table_base; - int16_t (*motion_val_base[2])[2]; - uint32_t *mb_type_base; #define MB_TYPE_INTRA MB_TYPE_INTRA4x4 //default mb_type if there is just one type #define IS_INTRA4x4(a) ((a)&MB_TYPE_INTRA4x4) #define IS_INTRA16x16(a) ((a)&MB_TYPE_INTRA16x16) @@ -137,16 +166,12 @@ typedef struct Picture{ int mb_var_sum; ///< sum of MB variance for current frame int mc_mb_var_sum; ///< motion compensated MB variance for current frame - uint16_t *mb_var; ///< Table for MB variances - uint16_t *mc_mb_var; ///< Table for motion compensated MB variances - uint8_t *mb_mean; ///< Table for MB luminance + int b_frame_score; /* */ - void *owner2; ///< pointer to the context that allocated this picture int needs_realloc; ///< Picture needs to be reallocated (eg due to a frame size change) - /** - * hardware accelerator private data - */ - void *hwaccel_picture_private; + + int reference; + int shared; } Picture; /** @@ -315,8 +340,6 @@ typedef struct MpegEncContext { Picture *last_picture_ptr; ///< pointer to the previous picture. Picture *next_picture_ptr; ///< pointer to the next picture (for bidir pred) Picture *current_picture_ptr; ///< pointer to the current picture - int picture_count; ///< number of allocated pictures (MAX_PICTURE_COUNT * avctx->thread_count) - int picture_range_start, picture_range_end; ///< the part of picture that this context can allocate in uint8_t *visualization_buffer[3]; ///< temporary buffer vor MV visualization int last_dc[3]; ///< last DC values for MPEG1 int16_t *dc_val_base; @@ -705,7 +728,7 @@ typedef struct MpegEncContext { #define REBASE_PICTURE(pic, new_ctx, old_ctx) \ ((pic && pic >= old_ctx->picture && \ - pic < old_ctx->picture + old_ctx->picture_count) ? \ + pic < old_ctx->picture + MAX_PICTURE_COUNT) ? \ &new_ctx->picture[pic - old_ctx->picture] : NULL) /* mpegvideo_enc common options */ @@ -770,7 +793,7 @@ void ff_draw_horiz_band(AVCodecContext *avctx, DSPContext *dsp, Picture *cur, int v_edge_pos, int h_edge_pos); void ff_mpeg_draw_horiz_band(MpegEncContext *s, int y, int h); void ff_mpeg_flush(AVCodecContext *avctx); -void ff_print_debug_info(MpegEncContext *s, AVFrame *pict); +void ff_print_debug_info(MpegEncContext *s, Picture *p); void ff_write_quant_matrix(PutBitContext *pb, uint16_t *matrix); void ff_release_unused_pictures(MpegEncContext *s, int remove_current); int ff_find_unused_picture(MpegEncContext *s, int shared); @@ -790,7 +813,6 @@ void ff_convert_matrix(DSPContext *dsp, int (*qmat)[64], uint16_t (*qmat16)[2][6 int ff_dct_quantize_c(MpegEncContext *s, int16_t *block, int n, int qscale, int *overflow); void ff_init_block_index(MpegEncContext *s); -void ff_copy_picture(Picture *dst, Picture *src); void ff_MPV_motion(MpegEncContext *s, uint8_t *dest_y, uint8_t *dest_cb, @@ -917,4 +939,7 @@ void ff_wmv2_encode_mb(MpegEncContext * s, int16_t block[6][64], int motion_x, int motion_y); +int ff_mpeg_ref_picture(MpegEncContext *s, Picture *dst, Picture *src); +void ff_mpeg_unref_picture(MpegEncContext *s, Picture *picture); + #endif /* AVCODEC_MPEGVIDEO_H */ diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c index bf094e6be1..96e2c73b71 100644 --- a/libavcodec/mpegvideo_enc.c +++ b/libavcodec/mpegvideo_enc.c @@ -177,7 +177,7 @@ void ff_write_quant_matrix(PutBitContext *pb, uint16_t *matrix) */ void ff_init_qscale_tab(MpegEncContext *s) { - int8_t * const qscale_table = s->current_picture.f.qscale_table; + int8_t * const qscale_table = s->current_picture.qscale_table; int i; for (i = 0; i < s->mb_num; i++) { @@ -871,9 +871,9 @@ static int get_intra_count(MpegEncContext *s, uint8_t *src, static int load_input_picture(MpegEncContext *s, const AVFrame *pic_arg) { - AVFrame *pic = NULL; + Picture *pic = NULL; int64_t pts; - int i, display_picture_number = 0; + int i, display_picture_number = 0, ret; const int encoding_delay = s->max_b_frames ? s->max_b_frames : (s->low_delay ? 0 : 1); int direct = 1; @@ -912,7 +912,7 @@ static int load_input_picture(MpegEncContext *s, const AVFrame *pic_arg) } if (pic_arg) { - if (encoding_delay && !(s->flags & CODEC_FLAG_INPUT_PRESERVED)) + if (!pic_arg->buf[0]); direct = 0; if (pic_arg->linesize[0] != s->linesize) direct = 0; @@ -929,14 +929,12 @@ static int load_input_picture(MpegEncContext *s, const AVFrame *pic_arg) if (i < 0) return i; - pic = &s->picture[i].f; + pic = &s->picture[i]; pic->reference = 3; - for (i = 0; i < 4; i++) { - pic->data[i] = pic_arg->data[i]; - pic->linesize[i] = pic_arg->linesize[i]; - } - if (ff_alloc_picture(s, (Picture *) pic, 1) < 0) { + if ((ret = av_frame_ref(&pic->f, pic_arg)) < 0) + return ret; + if (ff_alloc_picture(s, pic, 1) < 0) { return -1; } } else { @@ -944,16 +942,16 @@ static int load_input_picture(MpegEncContext *s, const AVFrame *pic_arg) if (i < 0) return i; - pic = &s->picture[i].f; + pic = &s->picture[i]; pic->reference = 3; - if (ff_alloc_picture(s, (Picture *) pic, 0) < 0) { + if (ff_alloc_picture(s, pic, 0) < 0) { return -1; } - if (pic->data[0] + INPLACE_OFFSET == pic_arg->data[0] && - pic->data[1] + INPLACE_OFFSET == pic_arg->data[1] && - pic->data[2] + INPLACE_OFFSET == pic_arg->data[2]) { + if (pic->f.data[0] + INPLACE_OFFSET == pic_arg->data[0] && + pic->f.data[1] + INPLACE_OFFSET == pic_arg->data[1] && + pic->f.data[2] + INPLACE_OFFSET == pic_arg->data[2]) { // empty } else { int h_chroma_shift, v_chroma_shift; @@ -969,7 +967,7 @@ static int load_input_picture(MpegEncContext *s, const AVFrame *pic_arg) int w = s->width >> h_shift; int h = s->height >> v_shift; uint8_t *src = pic_arg->data[i]; - uint8_t *dst = pic->data[i]; + uint8_t *dst = pic->f.data[i]; if (!s->avctx->rc_buffer_size) dst += INPLACE_OFFSET; @@ -986,9 +984,9 @@ static int load_input_picture(MpegEncContext *s, const AVFrame *pic_arg) } } } - copy_picture_attributes(s, pic, pic_arg); - pic->display_picture_number = display_picture_number; - pic->pts = pts; // we set this here to avoid modifiying pic_arg + copy_picture_attributes(s, &pic->f, pic_arg); + pic->f.display_picture_number = display_picture_number; + pic->f.pts = pts; // we set this here to avoid modifiying pic_arg } /* shift buffer entries */ @@ -1011,7 +1009,7 @@ static int skip_check(MpegEncContext *s, Picture *p, Picture *ref) const int bw = plane ? 1 : 2; for (y = 0; y < s->mb_height * bw; y++) { for (x = 0; x < s->mb_width * bw; x++) { - int off = p->f.type == FF_BUFFER_TYPE_SHARED ? 0 : 16; + int off = p->shared ? 0 : 16; uint8_t *dptr = p->f.data[plane] + 8 * (x + y * stride) + off; uint8_t *rptr = ref->f.data[plane] + 8 * (x + y * stride); int v = s->dsp.frame_skip_cmp[1](s, dptr, rptr, stride, 8); @@ -1107,7 +1105,7 @@ static int estimate_best_b_count(MpegEncContext *s) if (pre_input_ptr && (!i || s->input_picture[i - 1])) { pre_input = *pre_input_ptr; - if (pre_input.f.type != FF_BUFFER_TYPE_SHARED && i) { + if (!pre_input.shared && i) { pre_input.f.data[0] += INPLACE_OFFSET; pre_input.f.data[1] += INPLACE_OFFSET; pre_input.f.data[2] += INPLACE_OFFSET; @@ -1178,7 +1176,7 @@ static int estimate_best_b_count(MpegEncContext *s) static int select_input_picture(MpegEncContext *s) { - int i; + int i, ret; for (i = 1; i < MAX_PICTURE_COUNT; i++) s->reordered_input_picture[i - 1] = s->reordered_input_picture[i]; @@ -1199,17 +1197,7 @@ static int select_input_picture(MpegEncContext *s) if (s->picture_in_gop_number < s->gop_size && skip_check(s, s->input_picture[0], s->next_picture_ptr)) { // FIXME check that te gop check above is +-1 correct - if (s->input_picture[0]->f.type == FF_BUFFER_TYPE_SHARED) { - for (i = 0; i < 4; i++) - s->input_picture[0]->f.data[i] = NULL; - s->input_picture[0]->f.type = 0; - } else { - assert(s->input_picture[0]->f.type == FF_BUFFER_TYPE_USER || - s->input_picture[0]->f.type == FF_BUFFER_TYPE_INTERNAL); - - s->avctx->release_buffer(s->avctx, - &s->input_picture[0]->f); - } + av_frame_unref(&s->input_picture[0]->f); emms_c(); ff_vbv_update(s, 0); @@ -1313,14 +1301,15 @@ static int select_input_picture(MpegEncContext *s) } no_output_pic: if (s->reordered_input_picture[0]) { - s->reordered_input_picture[0]->f.reference = + s->reordered_input_picture[0]->reference = s->reordered_input_picture[0]->f.pict_type != AV_PICTURE_TYPE_B ? 3 : 0; - ff_copy_picture(&s->new_picture, s->reordered_input_picture[0]); + ff_mpeg_unref_picture(s, &s->new_picture); + if ((ret = ff_mpeg_ref_picture(s, &s->new_picture, s->reordered_input_picture[0]))) + return ret; - if (s->reordered_input_picture[0]->f.type == FF_BUFFER_TYPE_SHARED || - s->avctx->rc_buffer_size) { + if (s->reordered_input_picture[0]->shared || s->avctx->rc_buffer_size) { // input is a shared pix, so we can't modifiy it -> alloc a new // one & ensure that the shared one is reuseable @@ -1330,41 +1319,34 @@ no_output_pic: return i; pic = &s->picture[i]; - pic->f.reference = s->reordered_input_picture[0]->f.reference; + pic->reference = s->reordered_input_picture[0]->reference; if (ff_alloc_picture(s, pic, 0) < 0) { return -1; } - /* mark us unused / free shared pic */ - if (s->reordered_input_picture[0]->f.type == FF_BUFFER_TYPE_INTERNAL) - s->avctx->release_buffer(s->avctx, - &s->reordered_input_picture[0]->f); - for (i = 0; i < 4; i++) - s->reordered_input_picture[0]->f.data[i] = NULL; - s->reordered_input_picture[0]->f.type = 0; - copy_picture_attributes(s, &pic->f, &s->reordered_input_picture[0]->f); + /* mark us unused / free shared pic */ + av_frame_unref(&s->reordered_input_picture[0]->f); + s->reordered_input_picture[0]->shared = 0; + s->current_picture_ptr = pic; } else { // input is not a shared pix -> reuse buffer for current_pix - - assert(s->reordered_input_picture[0]->f.type == - FF_BUFFER_TYPE_USER || - s->reordered_input_picture[0]->f.type == - FF_BUFFER_TYPE_INTERNAL); - s->current_picture_ptr = s->reordered_input_picture[0]; for (i = 0; i < 4; i++) { s->new_picture.f.data[i] += INPLACE_OFFSET; } } - ff_copy_picture(&s->current_picture, s->current_picture_ptr); + ff_mpeg_unref_picture(s, &s->current_picture); + if ((ret = ff_mpeg_ref_picture(s, &s->current_picture, + s->current_picture_ptr)) < 0) + return ret; s->picture_number = s->new_picture.f.display_picture_number; } else { - memset(&s->new_picture, 0, sizeof(Picture)); + ff_mpeg_unref_picture(s, &s->new_picture); } return 0; } @@ -1712,7 +1694,7 @@ static av_always_inline void encode_mb_internal(MpegEncContext *s, update_qscale(s); if (!(s->mpv_flags & FF_MPV_FLAG_QP_RD)) { - s->qscale = s->current_picture_ptr->f.qscale_table[mb_xy]; + s->qscale = s->current_picture_ptr->qscale_table[mb_xy]; s->dquant = s->qscale - last_qp; if (s->out_format == FMT_H263) { @@ -2586,8 +2568,8 @@ static int encode_thread(AVCodecContext *c, void *arg){ s->mv_type = MV_TYPE_8X8; s->mb_intra= 0; for(i=0; i<4; i++){ - s->mv[0][i][0] = s->current_picture.f.motion_val[0][s->block_index[i]][0]; - s->mv[0][i][1] = s->current_picture.f.motion_val[0][s->block_index[i]][1]; + s->mv[0][i][0] = s->current_picture.motion_val[0][s->block_index[i]][0]; + s->mv[0][i][1] = s->current_picture.motion_val[0][s->block_index[i]][1]; } encode_mb_hq(s, &backup_s, &best_s, CANDIDATE_MB_TYPE_INTER4V, pb, pb2, tex_pb, &dmin, &next_block, 0, 0); @@ -2773,7 +2755,7 @@ static int encode_thread(AVCodecContext *c, void *arg){ } } - s->current_picture.f.qscale_table[xy] = best_s.qscale; + s->current_picture.qscale_table[xy] = best_s.qscale; copy_context_after_encode(s, &best_s, -1); @@ -2840,8 +2822,8 @@ static int encode_thread(AVCodecContext *c, void *arg){ s->mv_type = MV_TYPE_8X8; s->mb_intra= 0; for(i=0; i<4; i++){ - s->mv[0][i][0] = s->current_picture.f.motion_val[0][s->block_index[i]][0]; - s->mv[0][i][1] = s->current_picture.f.motion_val[0][s->block_index[i]][1]; + s->mv[0][i][0] = s->current_picture.motion_val[0][s->block_index[i]][0]; + s->mv[0][i][1] = s->current_picture.motion_val[0][s->block_index[i]][1]; } break; case CANDIDATE_MB_TYPE_DIRECT: diff --git a/libavcodec/mpegvideo_motion.c b/libavcodec/mpegvideo_motion.c index 24507a4575..0c86cfdafe 100644 --- a/libavcodec/mpegvideo_motion.c +++ b/libavcodec/mpegvideo_motion.c @@ -640,7 +640,7 @@ static av_always_inline void MPV_motion_internal(MpegEncContext *s, if(!is_mpeg12 && s->obmc && s->pict_type != AV_PICTURE_TYPE_B){ LOCAL_ALIGNED_8(int16_t, mv_cache, [4], [4][2]); - AVFrame *cur_frame = &s->current_picture.f; + Picture *cur_frame = &s->current_picture; const int xy= s->mb_x + s->mb_y*s->mb_stride; const int mot_stride= s->b8_stride; const int mot_xy= mb_x*2 + mb_y*2*mot_stride; diff --git a/libavcodec/mpegvideo_xvmc.c b/libavcodec/mpegvideo_xvmc.c index 6ebc307835..e95c91ff3a 100644 --- a/libavcodec/mpegvideo_xvmc.c +++ b/libavcodec/mpegvideo_xvmc.c @@ -178,7 +178,7 @@ void ff_xvmc_decode_mb(MpegEncContext *s) // Do I need to export quant when I could not perform postprocessing? // Anyway, it doesn't hurt. - s->current_picture.f.qscale_table[mb_xy] = s->qscale; + s->current_picture.qscale_table[mb_xy] = s->qscale; // start of XVMC-specific code render = (struct xvmc_pix_fmt*)s->current_picture.f.data[2]; diff --git a/libavcodec/msmpeg4.c b/libavcodec/msmpeg4.c index aeb6f5e7e4..e22a8e40f5 100644 --- a/libavcodec/msmpeg4.c +++ b/libavcodec/msmpeg4.c @@ -496,7 +496,7 @@ static int msmpeg4v34_decode_mb(MpegEncContext *s, int16_t block[6][64]) { int cbp, code, i; uint8_t *coded_val; - uint32_t * const mb_type_ptr = &s->current_picture.f.mb_type[s->mb_x + s->mb_y*s->mb_stride]; + uint32_t * const mb_type_ptr = &s->current_picture.mb_type[s->mb_x + s->mb_y*s->mb_stride]; if (s->pict_type == AV_PICTURE_TYPE_P) { if (s->use_skip_mb_code) { diff --git a/libavcodec/msrle.c b/libavcodec/msrle.c index c301b0c979..24fa523363 100644 --- a/libavcodec/msrle.c +++ b/libavcodec/msrle.c @@ -33,6 +33,7 @@ #include #include "avcodec.h" +#include "internal.h" #include "msrledec.h" typedef struct MsrleContext { @@ -83,9 +84,7 @@ static int msrle_decode_frame(AVCodecContext *avctx, s->buf = buf; s->size = buf_size; - s->frame.reference = 1; - s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE; - if ((ret = avctx->reget_buffer(avctx, &s->frame)) < 0) { + if ((ret = ff_reget_buffer(avctx, &s->frame)) < 0) { av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); return ret; } @@ -128,8 +127,10 @@ static int msrle_decode_frame(AVCodecContext *avctx, ff_msrle_decode(avctx, (AVPicture*)&s->frame, avctx->bits_per_coded_sample, &s->gb); } + if ((ret = av_frame_ref(data, &s->frame)) < 0) + return ret; + *got_frame = 1; - *(AVFrame*)data = s->frame; /* report that the buffer was completely consumed */ return buf_size; @@ -140,8 +141,7 @@ static av_cold int msrle_decode_end(AVCodecContext *avctx) MsrleContext *s = avctx->priv_data; /* release the last frame */ - if (s->frame.data[0]) - avctx->release_buffer(avctx, &s->frame); + av_frame_unref(&s->frame); return 0; } diff --git a/libavcodec/mss1.c b/libavcodec/mss1.c index c9edb2e2d7..dffdde5a15 100644 --- a/libavcodec/mss1.c +++ b/libavcodec/mss1.c @@ -25,6 +25,7 @@ */ #include "avcodec.h" +#include "internal.h" #include "mss12.h" typedef struct MSS1Context { @@ -150,10 +151,7 @@ static int mss1_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, init_get_bits(&gb, buf, buf_size * 8); arith_init(&acoder, &gb); - ctx->pic.reference = 3; - ctx->pic.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_READABLE | - FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE; - if ((ret = avctx->reget_buffer(avctx, &ctx->pic)) < 0) { + if ((ret = ff_reget_buffer(avctx, &ctx->pic)) < 0) { av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); return ret; } @@ -180,8 +178,10 @@ static int mss1_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, memcpy(ctx->pic.data[1], c->pal, AVPALETTE_SIZE); ctx->pic.palette_has_changed = pal_changed; + if ((ret = av_frame_ref(data, &ctx->pic)) < 0) + return ret; + *got_frame = 1; - *(AVFrame*)data = ctx->pic; /* always report that the buffer was completely consumed */ return buf_size; @@ -206,8 +206,7 @@ static av_cold int mss1_decode_end(AVCodecContext *avctx) { MSS1Context * const ctx = avctx->priv_data; - if (ctx->pic.data[0]) - avctx->release_buffer(avctx, &ctx->pic); + av_frame_unref(&ctx->pic); ff_mss12_decode_end(&ctx->ctx); return 0; diff --git a/libavcodec/mss2.c b/libavcodec/mss2.c index 190a09deff..6881f28824 100644 --- a/libavcodec/mss2.c +++ b/libavcodec/mss2.c @@ -34,7 +34,6 @@ typedef struct MSS2Context { VC1Context v; int split_position; - AVFrame pic; AVFrame last_pic; MSS12Context c; MSS2DSPContext dsp; @@ -470,6 +469,7 @@ static int mss2_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, int buf_size = avpkt->size; MSS2Context *ctx = avctx->priv_data; MSS12Context *c = &ctx->c; + AVFrame *frame = data; GetBitContext gb; GetByteContext gB; ArithCoder acoder; @@ -523,8 +523,8 @@ static int mss2_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, return AVERROR_INVALIDDATA; avctx->pix_fmt = is_555 ? AV_PIX_FMT_RGB555 : AV_PIX_FMT_RGB24; - if (ctx->pic.data[0] && ctx->pic.format != avctx->pix_fmt) - avctx->release_buffer(avctx, &ctx->pic); + if (ctx->last_pic.format != avctx->pix_fmt) + av_frame_unref(&ctx->last_pic); if (has_wmv9) { bytestream2_init(&gB, buf, buf_size + ARITH2_PADDING); @@ -596,25 +596,15 @@ static int mss2_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, } if (c->mvX < 0 || c->mvY < 0) { - FFSWAP(AVFrame, ctx->pic, ctx->last_pic); FFSWAP(uint8_t *, c->pal_pic, c->last_pal_pic); - if (ctx->pic.data[0]) - avctx->release_buffer(avctx, &ctx->pic); - - ctx->pic.reference = 3; - ctx->pic.buffer_hints = FF_BUFFER_HINTS_VALID | - FF_BUFFER_HINTS_READABLE | - FF_BUFFER_HINTS_PRESERVE | - FF_BUFFER_HINTS_REUSABLE; - - if ((ret = ff_get_buffer(avctx, &ctx->pic)) < 0) { + if ((ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } if (ctx->last_pic.data[0]) { - av_assert0(ctx->pic.linesize[0] == ctx->last_pic.linesize[0]); + av_assert0(frame->linesize[0] == ctx->last_pic.linesize[0]); c->last_rgb_pic = ctx->last_pic.data[0] + ctx->last_pic.linesize[0] * (avctx->height - 1); } else { @@ -622,28 +612,21 @@ static int mss2_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, return AVERROR_INVALIDDATA; } } else { - if (ctx->last_pic.data[0]) - avctx->release_buffer(avctx, &ctx->last_pic); - - ctx->pic.reference = 3; - ctx->pic.buffer_hints = FF_BUFFER_HINTS_VALID | - FF_BUFFER_HINTS_READABLE | - FF_BUFFER_HINTS_PRESERVE | - FF_BUFFER_HINTS_REUSABLE; - - if ((ret = avctx->reget_buffer(avctx, &ctx->pic)) < 0) { + if ((ret = ff_reget_buffer(avctx, &ctx->last_pic)) < 0) { av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); return ret; } + if ((ret = av_frame_ref(frame, &ctx->last_pic)) < 0) + return ret; c->last_rgb_pic = NULL; } - c->rgb_pic = ctx->pic.data[0] + - ctx->pic.linesize[0] * (avctx->height - 1); - c->rgb_stride = -ctx->pic.linesize[0]; + c->rgb_pic = frame->data[0] + + frame->linesize[0] * (avctx->height - 1); + c->rgb_stride = -frame->linesize[0]; - ctx->pic.key_frame = keyframe; - ctx->pic.pict_type = keyframe ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P; + frame->key_frame = keyframe; + frame->pict_type = keyframe ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P; if (is_555) { bytestream2_init(&gB, buf, buf_size); @@ -746,8 +729,14 @@ static int mss2_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, if (buf_size) av_log(avctx, AV_LOG_WARNING, "buffer not fully consumed\n"); + if (c->mvX < 0 || c->mvY < 0) { + av_frame_unref(&ctx->last_pic); + ret = av_frame_ref(&ctx->last_pic, frame); + if (ret < 0) + return ret; + } + *got_frame = 1; - *(AVFrame *)data = ctx->pic; return avpkt->size; } @@ -817,10 +806,7 @@ static av_cold int mss2_decode_end(AVCodecContext *avctx) { MSS2Context *const ctx = avctx->priv_data; - if (ctx->pic.data[0]) - avctx->release_buffer(avctx, &ctx->pic); - if (ctx->last_pic.data[0]) - avctx->release_buffer(avctx, &ctx->last_pic); + av_frame_unref(&ctx->last_pic); ff_mss12_decode_end(&ctx->c); av_freep(&ctx->c.pal_pic); @@ -836,7 +822,6 @@ static av_cold int mss2_decode_init(AVCodecContext *avctx) MSS12Context *c = &ctx->c; int ret; c->avctx = avctx; - avctx->coded_frame = &ctx->pic; if (ret = ff_mss12_decode_init(c, 1, &ctx->sc[0], &ctx->sc[1])) return ret; c->pal_stride = c->mask_stride; diff --git a/libavcodec/mss3.c b/libavcodec/mss3.c index 689daeee5d..fa5b99c454 100644 --- a/libavcodec/mss3.c +++ b/libavcodec/mss3.c @@ -27,6 +27,7 @@ #include "avcodec.h" #include "bytestream.h" #include "dsputil.h" +#include "internal.h" #include "mss34dsp.h" #define HEADER_SIZE 27 @@ -730,18 +731,16 @@ static int mss3_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, return buf_size; c->got_error = 0; - c->pic.reference = 3; - c->pic.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | - FF_BUFFER_HINTS_REUSABLE; - if ((ret = avctx->reget_buffer(avctx, &c->pic)) < 0) { + if ((ret = ff_reget_buffer(avctx, &c->pic)) < 0) { av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); return ret; } c->pic.key_frame = keyframe; c->pic.pict_type = keyframe ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P; if (!bytestream2_get_bytes_left(&gb)) { + if ((ret = av_frame_ref(data, &c->pic)) < 0) + return ret; *got_frame = 1; - *(AVFrame*)data = c->pic; return buf_size; } @@ -798,8 +797,10 @@ static int mss3_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, dst[2] += c->pic.linesize[2] * 8; } + if ((ret = av_frame_ref(data, &c->pic)) < 0) + return ret; + *got_frame = 1; - *(AVFrame*)data = c->pic; return buf_size; } @@ -836,7 +837,6 @@ static av_cold int mss3_decode_init(AVCodecContext *avctx) } avctx->pix_fmt = AV_PIX_FMT_YUV420P; - avctx->coded_frame = &c->pic; init_coders(c); @@ -848,8 +848,7 @@ static av_cold int mss3_decode_end(AVCodecContext *avctx) MSS3Context * const c = avctx->priv_data; int i; - if (c->pic.data[0]) - avctx->release_buffer(avctx, &c->pic); + av_frame_unref(&c->pic); for (i = 0; i < 3; i++) av_freep(&c->dct_coder[i].prev_dc); diff --git a/libavcodec/mss4.c b/libavcodec/mss4.c index f4e4d8ddb4..a74c363dda 100644 --- a/libavcodec/mss4.c +++ b/libavcodec/mss4.c @@ -29,6 +29,7 @@ #include "bytestream.h" #include "dsputil.h" #include "get_bits.h" +#include "internal.h" #include "mss34dsp.h" #include "unary.h" @@ -553,11 +554,7 @@ static int mss4_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, return AVERROR_INVALIDDATA; } - c->pic.reference = 3; - c->pic.buffer_hints = FF_BUFFER_HINTS_VALID | - FF_BUFFER_HINTS_PRESERVE | - FF_BUFFER_HINTS_REUSABLE; - if ((ret = avctx->reget_buffer(avctx, &c->pic)) < 0) { + if ((ret = ff_reget_buffer(avctx, &c->pic)) < 0) { av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); return ret; } @@ -566,7 +563,8 @@ static int mss4_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, : AV_PICTURE_TYPE_P; if (frame_type == SKIP_FRAME) { *got_frame = 1; - *(AVFrame*)data = c->pic; + if ((ret = av_frame_ref(data, &c->pic)) < 0) + return ret; return buf_size; } @@ -622,8 +620,10 @@ static int mss4_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, dst[2] += c->pic.linesize[2] * 16; } + if ((ret = av_frame_ref(data, &c->pic)) < 0) + return ret; + *got_frame = 1; - *(AVFrame*)data = c->pic; return buf_size; } @@ -649,7 +649,6 @@ static av_cold int mss4_decode_init(AVCodecContext *avctx) } avctx->pix_fmt = AV_PIX_FMT_YUV444P; - avctx->coded_frame = &c->pic; return 0; } @@ -659,8 +658,7 @@ static av_cold int mss4_decode_end(AVCodecContext *avctx) MSS4Context * const c = avctx->priv_data; int i; - if (c->pic.data[0]) - avctx->release_buffer(avctx, &c->pic); + av_frame_unref(&c->pic); for (i = 0; i < 3; i++) av_freep(&c->prev_dc[i]); mss4_free_vlcs(c); diff --git a/libavcodec/msvideo1.c b/libavcodec/msvideo1.c index 860a893118..d0aee12d49 100644 --- a/libavcodec/msvideo1.c +++ b/libavcodec/msvideo1.c @@ -34,6 +34,7 @@ #include "libavutil/internal.h" #include "libavutil/intreadwrite.h" #include "avcodec.h" +#include "internal.h" #define PALETTE_COUNT 256 #define CHECK_STREAM_PTR(n) \ @@ -292,15 +293,14 @@ static int msvideo1_decode_frame(AVCodecContext *avctx, const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; Msvideo1Context *s = avctx->priv_data; + int ret; s->buf = buf; s->size = buf_size; - s->frame.reference = 1; - s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE; - if (avctx->reget_buffer(avctx, &s->frame)) { + if ((ret = ff_reget_buffer(avctx, &s->frame)) < 0) { av_log(s->avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); - return -1; + return ret; } if (s->mode_8bit) { @@ -317,8 +317,10 @@ static int msvideo1_decode_frame(AVCodecContext *avctx, else msvideo1_decode_16bit(s); + if ((ret = av_frame_ref(data, &s->frame)) < 0) + return ret; + *got_frame = 1; - *(AVFrame*)data = s->frame; /* report that the buffer was completely consumed */ return buf_size; @@ -328,8 +330,7 @@ static av_cold int msvideo1_decode_end(AVCodecContext *avctx) { Msvideo1Context *s = avctx->priv_data; - if (s->frame.data[0]) - avctx->release_buffer(avctx, &s->frame); + av_frame_unref(&s->frame); return 0; } diff --git a/libavcodec/mxpegdec.c b/libavcodec/mxpegdec.c index d81e9fc853..68c06c2cd9 100644 --- a/libavcodec/mxpegdec.c +++ b/libavcodec/mxpegdec.c @@ -46,7 +46,6 @@ static av_cold int mxpeg_decode_init(AVCodecContext *avctx) { MXpegDecodeContext *s = avctx->priv_data; - s->picture[0].reference = s->picture[1].reference = 3; s->jpg.picture_ptr = &s->picture[0]; return ff_mjpeg_decode_init(avctx); } @@ -167,7 +166,6 @@ static int mxpeg_decode_frame(AVCodecContext *avctx, const uint8_t *unescaped_buf_ptr; int unescaped_buf_size; int start_code; - AVFrame *picture = data; int ret; buf_ptr = buf; @@ -248,9 +246,9 @@ static int mxpeg_decode_frame(AVCodecContext *avctx, break; } /* use stored SOF data to allocate current picture */ - if (jpg->picture_ptr->data[0]) - avctx->release_buffer(avctx, jpg->picture_ptr); - if (ff_get_buffer(avctx, jpg->picture_ptr) < 0) { + av_frame_unref(jpg->picture_ptr); + if (ff_get_buffer(avctx, jpg->picture_ptr, + AV_GET_BUFFER_FLAG_REF) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return AVERROR(ENOMEM); } @@ -269,7 +267,8 @@ static int mxpeg_decode_frame(AVCodecContext *avctx, /* allocate dummy reference picture if needed */ if (!reference_ptr->data[0] && - ff_get_buffer(avctx, reference_ptr) < 0) { + ff_get_buffer(avctx, reference_ptr, + AV_GET_BUFFER_FLAG_REF) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return AVERROR(ENOMEM); } @@ -293,8 +292,11 @@ static int mxpeg_decode_frame(AVCodecContext *avctx, the_end: if (jpg->got_picture) { + int ret = av_frame_ref(data, jpg->picture_ptr); + if (ret < 0) + return ret; *got_frame = 1; - *picture = *jpg->picture_ptr; + s->picture_index ^= 1; jpg->picture_ptr = &s->picture[s->picture_index]; @@ -318,10 +320,8 @@ static av_cold int mxpeg_decode_end(AVCodecContext *avctx) jpg->picture_ptr = NULL; ff_mjpeg_decode_end(avctx); - for (i = 0; i < 2; ++i) { - if (s->picture[i].data[0]) - avctx->release_buffer(avctx, &s->picture[i]); - } + for (i = 0; i < 2; ++i) + av_frame_unref(&s->picture[i]); av_freep(&s->mxm_bitmask); av_freep(&s->completion_bitmask); diff --git a/libavcodec/nellymoserdec.c b/libavcodec/nellymoserdec.c index d78916b1c9..cfd0709f0a 100644 --- a/libavcodec/nellymoserdec.c +++ b/libavcodec/nellymoserdec.c @@ -166,7 +166,7 @@ static int decode_tag(AVCodecContext *avctx, void *data, /* get output buffer */ frame->nb_samples = NELLY_SAMPLES * blocks; - if ((ret = ff_get_buffer(avctx, frame)) < 0) { + if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } diff --git a/libavcodec/nuv.c b/libavcodec/nuv.c index 193bed6e71..4d5063fad7 100644 --- a/libavcodec/nuv.c +++ b/libavcodec/nuv.c @@ -27,6 +27,7 @@ #include "libavutil/lzo.h" #include "libavutil/imgutils.h" #include "avcodec.h" +#include "internal.h" #include "rtjpeg.h" typedef struct { @@ -220,14 +221,12 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, buf_size -= RTJPEG_HEADER_SIZE; } - if (keyframe && c->pic.data[0]) { - avctx->release_buffer(avctx, &c->pic); + if (keyframe) { + av_frame_unref(&c->pic); init_frame = 1; } - c->pic.reference = 3; - c->pic.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_READABLE | - FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE; - result = avctx->reget_buffer(avctx, &c->pic); + + result = ff_reget_buffer(avctx, &c->pic); if (result < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return result; @@ -269,7 +268,9 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, return AVERROR_INVALIDDATA; } - *picture = c->pic; + if ((result = av_frame_ref(picture, &c->pic)) < 0) + return result; + *got_frame = 1; return orig_size; } @@ -304,8 +305,7 @@ static av_cold int decode_end(AVCodecContext *avctx) NuvContext *c = avctx->priv_data; av_freep(&c->decomp_buf); - if (c->pic.data[0]) - avctx->release_buffer(avctx, &c->pic); + av_frame_unref(&c->pic); return 0; } diff --git a/libavcodec/options.c b/libavcodec/options.c index fc2a184221..d140552711 100644 --- a/libavcodec/options.c +++ b/libavcodec/options.c @@ -88,8 +88,7 @@ int avcodec_get_context_defaults3(AVCodecContext *s, const AVCodec *codec) av_opt_set_defaults(s); s->time_base = (AVRational){0,1}; - s->get_buffer = avcodec_default_get_buffer; - s->release_buffer = avcodec_default_release_buffer; + s->get_buffer2 = avcodec_default_get_buffer2; s->get_format = avcodec_default_get_format; s->execute = avcodec_default_execute; s->execute2 = avcodec_default_execute2; @@ -97,7 +96,6 @@ int avcodec_get_context_defaults3(AVCodecContext *s, const AVCodec *codec) s->pix_fmt = AV_PIX_FMT_NONE; s->sample_fmt = AV_SAMPLE_FMT_NONE; - s->reget_buffer = avcodec_default_reget_buffer; s->reordered_opaque = AV_NOPTS_VALUE; if(codec && codec->priv_data_size){ if(!s->priv_data){ diff --git a/libavcodec/options_table.h b/libavcodec/options_table.h index 7d0795a580..28ce352628 100644 --- a/libavcodec/options_table.h +++ b/libavcodec/options_table.h @@ -403,6 +403,7 @@ static const AVOption options[]={ {"s32p", "32-bit signed integer planar", 0, AV_OPT_TYPE_CONST, {.i64 = AV_SAMPLE_FMT_S32P }, INT_MIN, INT_MAX, A|D, "request_sample_fmt"}, {"fltp", "32-bit float planar", 0, AV_OPT_TYPE_CONST, {.i64 = AV_SAMPLE_FMT_FLTP }, INT_MIN, INT_MAX, A|D, "request_sample_fmt"}, {"dblp", "64-bit double planar", 0, AV_OPT_TYPE_CONST, {.i64 = AV_SAMPLE_FMT_DBLP }, INT_MIN, INT_MAX, A|D, "request_sample_fmt"}, +{"refcounted_frames", NULL, OFFSET(refcounted_frames), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, A|V|D }, {NULL}, }; diff --git a/libavcodec/pcm-mpeg.c b/libavcodec/pcm-mpeg.c index 41bcb3e395..e13e2b06c3 100644 --- a/libavcodec/pcm-mpeg.c +++ b/libavcodec/pcm-mpeg.c @@ -152,7 +152,7 @@ static int pcm_bluray_decode_frame(AVCodecContext *avctx, void *data, /* get output buffer */ frame->nb_samples = samples; - if ((retval = ff_get_buffer(avctx, frame)) < 0) { + if ((retval = ff_get_buffer(avctx, frame, 0)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return retval; } diff --git a/libavcodec/pcm.c b/libavcodec/pcm.c index 64a230ae03..c56a95e3b5 100644 --- a/libavcodec/pcm.c +++ b/libavcodec/pcm.c @@ -299,7 +299,7 @@ static int pcm_decode_frame(AVCodecContext *avctx, void *data, /* get output buffer */ frame->nb_samples = n * samples_per_block / avctx->channels; - if ((ret = ff_get_buffer(avctx, frame)) < 0) { + if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } diff --git a/libavcodec/pcx.c b/libavcodec/pcx.c index 04770a9ad2..949ea1ca70 100644 --- a/libavcodec/pcx.c +++ b/libavcodec/pcx.c @@ -28,19 +28,6 @@ #include "get_bits.h" #include "internal.h" -typedef struct PCXContext { - AVFrame picture; -} PCXContext; - -static av_cold int pcx_init(AVCodecContext *avctx) { - PCXContext *s = avctx->priv_data; - - avcodec_get_frame_defaults(&s->picture); - avctx->coded_frame= &s->picture; - - return 0; -} - /** * @return advanced src pointer */ @@ -81,9 +68,7 @@ static int pcx_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; - PCXContext * const s = avctx->priv_data; - AVFrame *picture = data; - AVFrame * const p = &s->picture; + AVFrame * const p = data; int compressed, xmin, ymin, xmax, ymax; unsigned int w, h, bits_per_pixel, bytes_per_line, nplanes, stride, y, x, bytes_per_scanline; @@ -141,14 +126,11 @@ static int pcx_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, buf += 128; - if (p->data[0]) - avctx->release_buffer(avctx, p); - if ((ret = av_image_check_size(w, h, 0, avctx)) < 0) return ret; if (w != avctx->width || h != avctx->height) avcodec_set_dimensions(avctx, w, h); - if ((ret = ff_get_buffer(avctx, p)) < 0) { + if ((ret = ff_get_buffer(avctx, p, 0)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } @@ -230,7 +212,6 @@ static int pcx_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, pcx_palette(&palette, (uint32_t *) p->data[1], 16); } - *picture = s->picture; *got_frame = 1; ret = buf - bufstart; @@ -239,22 +220,10 @@ end: return ret; } -static av_cold int pcx_end(AVCodecContext *avctx) { - PCXContext *s = avctx->priv_data; - - if(s->picture.data[0]) - avctx->release_buffer(avctx, &s->picture); - - return 0; -} - AVCodec ff_pcx_decoder = { .name = "pcx", .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_PCX, - .priv_data_size = sizeof(PCXContext), - .init = pcx_init, - .close = pcx_end, .decode = pcx_decode_frame, .capabilities = CODEC_CAP_DR1, .long_name = NULL_IF_CONFIG_SMALL("PC Paintbrush PCX image"), diff --git a/libavcodec/pictordec.c b/libavcodec/pictordec.c index 16f930730b..322d3d4ad2 100644 --- a/libavcodec/pictordec.c +++ b/libavcodec/pictordec.c @@ -31,16 +31,16 @@ #include "internal.h" typedef struct PicContext { - AVFrame frame; int width, height; int nb_planes; GetByteContext g; } PicContext; -static void picmemset_8bpp(PicContext *s, int value, int run, int *x, int *y) +static void picmemset_8bpp(PicContext *s, AVFrame *frame, int value, int run, + int *x, int *y) { while (run > 0) { - uint8_t *d = s->frame.data[0] + *y * s->frame.linesize[0]; + uint8_t *d = frame->data[0] + *y * frame->linesize[0]; if (*x + run >= s->width) { int n = s->width - *x; memset(d + *x, value, n); @@ -57,7 +57,7 @@ static void picmemset_8bpp(PicContext *s, int value, int run, int *x, int *y) } } -static void picmemset(PicContext *s, int value, int run, +static void picmemset(PicContext *s, AVFrame *frame, int value, int run, int *x, int *y, int *plane, int bits_per_plane) { uint8_t *d; @@ -68,7 +68,7 @@ static void picmemset(PicContext *s, int value, int run, while (run > 0) { int j; for (j = 8-bits_per_plane; j >= 0; j -= bits_per_plane) { - d = s->frame.data[0] + *y * s->frame.linesize[0]; + d = frame->data[0] + *y * frame->linesize[0]; d[*x] |= (value >> j) & mask; *x += 1; if (*x == s->width) { @@ -102,9 +102,10 @@ static int decode_frame(AVCodecContext *avctx, AVPacket *avpkt) { PicContext *s = avctx->priv_data; + AVFrame *frame = data; uint32_t *palette; int bits_per_plane, bpp, etype, esize, npal, pos_after_pal; - int i, x, y, plane, tmp; + int i, x, y, plane, tmp, ret; bytestream2_init(&s->g, avpkt->data, avpkt->size); @@ -143,20 +144,18 @@ static int decode_frame(AVCodecContext *avctx, if (av_image_check_size(s->width, s->height, 0, avctx) < 0) return -1; avcodec_set_dimensions(avctx, s->width, s->height); - if (s->frame.data[0]) - avctx->release_buffer(avctx, &s->frame); } - if (ff_get_buffer(avctx, &s->frame) < 0){ + if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); - return -1; + return ret; } - memset(s->frame.data[0], 0, s->height * s->frame.linesize[0]); - s->frame.pict_type = AV_PICTURE_TYPE_I; - s->frame.palette_has_changed = 1; + memset(frame->data[0], 0, s->height * frame->linesize[0]); + frame->pict_type = AV_PICTURE_TYPE_I; + frame->palette_has_changed = 1; pos_after_pal = bytestream2_tell(&s->g) + esize; - palette = (uint32_t*)s->frame.data[1]; + palette = (uint32_t*)frame->data[1]; if (etype == 1 && esize > 1 && bytestream2_peek_byte(&s->g) < 6) { int idx = bytestream2_get_byte(&s->g); npal = 4; @@ -225,11 +224,11 @@ static int decode_frame(AVCodecContext *avctx, break; if (bits_per_plane == 8) { - picmemset_8bpp(s, val, run, &x, &y); + picmemset_8bpp(s, frame, val, run, &x, &y); if (y < 0) break; } else { - picmemset(s, val, run, &x, &y, &plane, bits_per_plane); + picmemset(s, frame, val, run, &x, &y, &plane, bits_per_plane); } } } @@ -239,24 +238,14 @@ static int decode_frame(AVCodecContext *avctx, } *got_frame = 1; - *(AVFrame*)data = s->frame; return avpkt->size; } -static av_cold int decode_end(AVCodecContext *avctx) -{ - PicContext *s = avctx->priv_data; - if (s->frame.data[0]) - avctx->release_buffer(avctx, &s->frame); - return 0; -} - AVCodec ff_pictor_decoder = { .name = "pictor", .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_PICTOR, .priv_data_size = sizeof(PicContext), - .close = decode_end, .decode = decode_frame, .capabilities = CODEC_CAP_DR1, .long_name = NULL_IF_CONFIG_SMALL("Pictor/PC Paint"), diff --git a/libavcodec/pngdec.c b/libavcodec/pngdec.c index b4e1faeae8..5b82298d22 100644 --- a/libavcodec/pngdec.c +++ b/libavcodec/pngdec.c @@ -37,8 +37,7 @@ typedef struct PNGDecContext { PNGDSPContext dsp; GetByteContext gb; - AVFrame picture1, picture2; - AVFrame *current_picture, *last_picture; + AVFrame *prev; int state; int width, height; @@ -392,16 +391,11 @@ static int decode_frame(AVCodecContext *avctx, PNGDecContext * const s = avctx->priv_data; const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; - AVFrame *picture = data; + AVFrame *p = data; uint8_t *crow_buf_base = NULL; - AVFrame *p; uint32_t tag, length; int ret; - FFSWAP(AVFrame *, s->current_picture, s->last_picture); - avctx->coded_frame = s->current_picture; - p = s->current_picture; - /* check signature */ if (buf_size < 8 || memcmp(buf, ff_pngsig, 8) != 0 && @@ -492,11 +486,8 @@ static int decode_frame(AVCodecContext *avctx, } else { goto fail; } - if (p->data[0]) - avctx->release_buffer(avctx, p); - p->reference = 0; - if (ff_get_buffer(avctx, p) < 0) { + if (ff_get_buffer(avctx, p, AV_GET_BUFFER_FLAG_REF) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); goto fail; } @@ -597,11 +588,11 @@ static int decode_frame(AVCodecContext *avctx, } exit_loop: /* handle p-frames only if a predecessor frame is available */ - if (s->last_picture->data[0] != NULL) { + if (s->prev->data[0]) { if (!(avpkt->flags & AV_PKT_FLAG_KEY)) { int i, j; - uint8_t *pd = s->current_picture->data[0]; - uint8_t *pd_last = s->last_picture->data[0]; + uint8_t *pd = p->data[0]; + uint8_t *pd_last = s->prev->data[0]; for (j = 0; j < s->height; j++) { for (i = 0; i < s->width * s->bpp; i++) { @@ -613,7 +604,10 @@ static int decode_frame(AVCodecContext *avctx, } } - *picture = *s->current_picture; + av_frame_unref(s->prev); + if ((ret = av_frame_ref(s->prev, p)) < 0) + goto fail; + *got_frame = 1; ret = bytestream2_tell(&s->gb); @@ -633,10 +627,10 @@ static av_cold int png_dec_init(AVCodecContext *avctx) { PNGDecContext *s = avctx->priv_data; - s->current_picture = &s->picture1; - s->last_picture = &s->picture2; - avcodec_get_frame_defaults(&s->picture1); - avcodec_get_frame_defaults(&s->picture2); + s->prev = av_frame_alloc(); + if (!s->prev) + return AVERROR(ENOMEM); + ff_pngdsp_init(&s->dsp); return 0; @@ -646,10 +640,7 @@ static av_cold int png_dec_end(AVCodecContext *avctx) { PNGDecContext *s = avctx->priv_data; - if (s->picture1.data[0]) - avctx->release_buffer(avctx, &s->picture1); - if (s->picture2.data[0]) - avctx->release_buffer(avctx, &s->picture2); + av_frame_free(&s->prev); return 0; } diff --git a/libavcodec/pnm.c b/libavcodec/pnm.c index 5f2fa4966c..9d7c68dc64 100644 --- a/libavcodec/pnm.c +++ b/libavcodec/pnm.c @@ -185,16 +185,6 @@ int ff_pnm_decode_header(AVCodecContext *avctx, PNMContext * const s) return 0; } -av_cold int ff_pnm_end(AVCodecContext *avctx) -{ - PNMContext *s = avctx->priv_data; - - if (s->picture.data[0]) - avctx->release_buffer(avctx, &s->picture); - - return 0; -} - av_cold int ff_pnm_init(AVCodecContext *avctx) { PNMContext *s = avctx->priv_data; diff --git a/libavcodec/pnm.h b/libavcodec/pnm.h index efba0d8183..ec5ebdb4fe 100644 --- a/libavcodec/pnm.h +++ b/libavcodec/pnm.h @@ -34,7 +34,6 @@ typedef struct PNMContext { } PNMContext; int ff_pnm_decode_header(AVCodecContext *avctx, PNMContext * const s); -int ff_pnm_end(AVCodecContext *avctx); int ff_pnm_init(AVCodecContext *avctx); #endif /* AVCODEC_PNM_H */ diff --git a/libavcodec/pnmdec.c b/libavcodec/pnmdec.c index c9b873d468..38056fbbe1 100644 --- a/libavcodec/pnmdec.c +++ b/libavcodec/pnmdec.c @@ -32,8 +32,7 @@ static int pnm_decode_frame(AVCodecContext *avctx, void *data, const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; PNMContext * const s = avctx->priv_data; - AVFrame *picture = data; - AVFrame * const p = &s->picture; + AVFrame * const p = data; int i, j, n, linesize, h, upgrade = 0; unsigned char *ptr; int components, sample_len, ret; @@ -45,11 +44,7 @@ static int pnm_decode_frame(AVCodecContext *avctx, void *data, if ((ret = ff_pnm_decode_header(avctx, s)) < 0) return ret; - if (p->data[0]) - avctx->release_buffer(avctx, p); - - p->reference = 0; - if ((ret = ff_get_buffer(avctx, p)) < 0) { + if ((ret = ff_get_buffer(avctx, p, 0)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } @@ -226,7 +221,6 @@ static int pnm_decode_frame(AVCodecContext *avctx, void *data, } break; } - *picture = s->picture; *got_frame = 1; return s->bytestream - s->bytestream_start; @@ -239,8 +233,6 @@ AVCodec ff_pgm_decoder = { .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_PGM, .priv_data_size = sizeof(PNMContext), - .init = ff_pnm_init, - .close = ff_pnm_end, .decode = pnm_decode_frame, .capabilities = CODEC_CAP_DR1, .long_name = NULL_IF_CONFIG_SMALL("PGM (Portable GrayMap) image"), @@ -253,8 +245,6 @@ AVCodec ff_pgmyuv_decoder = { .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_PGMYUV, .priv_data_size = sizeof(PNMContext), - .init = ff_pnm_init, - .close = ff_pnm_end, .decode = pnm_decode_frame, .capabilities = CODEC_CAP_DR1, .long_name = NULL_IF_CONFIG_SMALL("PGMYUV (Portable GrayMap YUV) image"), @@ -267,8 +257,6 @@ AVCodec ff_ppm_decoder = { .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_PPM, .priv_data_size = sizeof(PNMContext), - .init = ff_pnm_init, - .close = ff_pnm_end, .decode = pnm_decode_frame, .capabilities = CODEC_CAP_DR1, .long_name = NULL_IF_CONFIG_SMALL("PPM (Portable PixelMap) image"), @@ -281,8 +269,6 @@ AVCodec ff_pbm_decoder = { .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_PBM, .priv_data_size = sizeof(PNMContext), - .init = ff_pnm_init, - .close = ff_pnm_end, .decode = pnm_decode_frame, .capabilities = CODEC_CAP_DR1, .long_name = NULL_IF_CONFIG_SMALL("PBM (Portable BitMap) image"), @@ -295,8 +281,6 @@ AVCodec ff_pam_decoder = { .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_PAM, .priv_data_size = sizeof(PNMContext), - .init = ff_pnm_init, - .close = ff_pnm_end, .decode = pnm_decode_frame, .capabilities = CODEC_CAP_DR1, .long_name = NULL_IF_CONFIG_SMALL("PAM (Portable AnyMap) image"), diff --git a/libavcodec/proresdec.c b/libavcodec/proresdec.c index f4c6b6d951..27226c04ca 100644 --- a/libavcodec/proresdec.c +++ b/libavcodec/proresdec.c @@ -53,7 +53,7 @@ typedef struct { typedef struct { ProresDSPContext dsp; - AVFrame picture; + AVFrame *frame; ScanTable scantable; int scantable_type; ///< -1 = uninitialized, 0 = progressive, 1/2 = interlaced @@ -88,11 +88,6 @@ static av_cold int decode_init(AVCodecContext *avctx) avctx->bits_per_raw_sample = PRORES_BITS_PER_SAMPLE; ff_proresdsp_init(&ctx->dsp); - avctx->coded_frame = &ctx->picture; - avcodec_get_frame_defaults(&ctx->picture); - ctx->picture.type = AV_PICTURE_TYPE_I; - ctx->picture.key_frame = 1; - ctx->scantable_type = -1; // set scantable type to uninitialized memset(ctx->qmat_luma, 4, 64); memset(ctx->qmat_chroma, 4, 64); @@ -163,10 +158,10 @@ static int decode_frame_header(ProresContext *ctx, const uint8_t *buf, } if (ctx->frame_type) { /* if interlaced */ - ctx->picture.interlaced_frame = 1; - ctx->picture.top_field_first = ctx->frame_type & 1; + ctx->frame->interlaced_frame = 1; + ctx->frame->top_field_first = ctx->frame_type & 1; } else { - ctx->picture.interlaced_frame = 0; + ctx->frame->interlaced_frame = 0; } avctx->color_primaries = buf[14]; @@ -247,8 +242,8 @@ static int decode_picture_header(ProresContext *ctx, const uint8_t *buf, ctx->num_x_mbs = (avctx->width + 15) >> 4; ctx->num_y_mbs = (avctx->height + - (1 << (4 + ctx->picture.interlaced_frame)) - 1) >> - (4 + ctx->picture.interlaced_frame); + (1 << (4 + ctx->frame->interlaced_frame)) - 1) >> + (4 + ctx->frame->interlaced_frame); remainder = ctx->num_x_mbs & ((1 << slice_width_factor) - 1); num_x_slices = (ctx->num_x_mbs >> slice_width_factor) + (remainder & 1) + @@ -482,7 +477,7 @@ static int decode_slice(AVCodecContext *avctx, void *tdata) int mbs_per_slice = td->slice_width; const uint8_t *buf; uint8_t *y_data, *u_data, *v_data; - AVFrame *pic = avctx->coded_frame; + AVFrame *pic = ctx->frame; int i, sf, slice_width_factor; int slice_data_size, hdr_size, y_data_size, u_data_size, v_data_size; int y_linesize, u_linesize, v_linesize; @@ -606,11 +601,14 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { ProresContext *ctx = avctx->priv_data; - AVFrame *picture = avctx->coded_frame; const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; int frame_hdr_size, pic_num, pic_data_size; + ctx->frame = data; + ctx->frame->pict_type = AV_PICTURE_TYPE_I; + ctx->frame->key_frame = 1; + /* check frame atom container */ if (buf_size < 28 || buf_size < AV_RB32(buf) || AV_RB32(buf + 4) != FRAME_ID) { @@ -626,14 +624,10 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, MOVE_DATA_PTR(frame_hdr_size); - if (picture->data[0]) - avctx->release_buffer(avctx, picture); - - picture->reference = 0; - if (ff_get_buffer(avctx, picture) < 0) + if (ff_get_buffer(avctx, ctx->frame, 0) < 0) return -1; - for (pic_num = 0; ctx->picture.interlaced_frame - pic_num + 1; pic_num++) { + for (pic_num = 0; ctx->frame->interlaced_frame - pic_num + 1; pic_num++) { pic_data_size = decode_picture_header(ctx, buf, buf_size, avctx); if (pic_data_size < 0) return AVERROR_INVALIDDATA; @@ -644,8 +638,8 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, MOVE_DATA_PTR(pic_data_size); } - *got_frame = 1; - *(AVFrame*) data = *avctx->coded_frame; + ctx->frame = NULL; + *got_frame = 1; return avpkt->size; } @@ -655,9 +649,6 @@ static av_cold int decode_close(AVCodecContext *avctx) { ProresContext *ctx = avctx->priv_data; - if (ctx->picture.data[0]) - avctx->release_buffer(avctx, &ctx->picture); - av_freep(&ctx->slice_data); return 0; diff --git a/libavcodec/pthread.c b/libavcodec/pthread.c index 751fca8d6d..280c08ed8b 100644 --- a/libavcodec/pthread.c +++ b/libavcodec/pthread.c @@ -52,6 +52,7 @@ #include "avcodec.h" #include "internal.h" #include "thread.h" +#include "libavutil/avassert.h" #include "libavutil/common.h" #if HAVE_PTHREADS @@ -80,9 +81,6 @@ typedef struct ThreadContext { int done; } ThreadContext; -/// Max number of frame buffers that can be allocated when using frame threads. -#define MAX_BUFFERS (32+1) - /** * Context used by codec threads and stored in their AVCodecContext thread_opaque. */ @@ -122,16 +120,12 @@ typedef struct PerThreadContext { * Array of frames passed to ff_thread_release_buffer(). * Frames are released after all threads referencing them are finished. */ - AVFrame released_buffers[MAX_BUFFERS]; - int num_released_buffers; - - /** - * Array of progress values used by ff_thread_get_buffer(). - */ - int progress[MAX_BUFFERS][2]; - uint8_t progress_used[MAX_BUFFERS]; + AVFrame *released_buffers; + int num_released_buffers; + int released_buffers_allocated; AVFrame *requested_frame; ///< AVFrame the codec passed to get_buffer() + int requested_flags; ///< flags passed to get_buffer() for requested_frame } PerThreadContext; /** @@ -459,8 +453,11 @@ static int update_context_from_user(AVCodecContext *dst, AVCodecContext *src) dst->flags = src->flags; dst->draw_horiz_band= src->draw_horiz_band; + dst->get_buffer2 = src->get_buffer2; +#if FF_API_GET_BUFFER dst->get_buffer = src->get_buffer; dst->release_buffer = src->release_buffer; +#endif dst->opaque = src->opaque; dst->debug = src->debug; @@ -492,14 +489,6 @@ static int update_context_from_user(AVCodecContext *dst, AVCodecContext *src) #undef copy_fields } -static void free_progress(AVFrame *f) -{ - PerThreadContext *p = f->owner->thread_opaque; - int *progress = f->thread_opaque; - - p->progress_used[(progress - p->progress[0]) / 2] = 0; -} - /// Releases the buffers that this decoding thread was the last user of. static void release_delayed_buffers(PerThreadContext *p) { @@ -509,11 +498,13 @@ static void release_delayed_buffers(PerThreadContext *p) AVFrame *f; pthread_mutex_lock(&fctx->buffer_mutex); - f = &p->released_buffers[--p->num_released_buffers]; - free_progress(f); - f->thread_opaque = NULL; - f->owner->release_buffer(f->owner, f); + // fix extended data in case the caller screwed it up + av_assert0(p->avctx->codec_type == AVMEDIA_TYPE_VIDEO); + f = &p->released_buffers[--p->num_released_buffers]; + f->extended_data = f->data; + av_frame_unref(f); + pthread_mutex_unlock(&fctx->buffer_mutex); } } @@ -567,15 +558,18 @@ static int submit_packet(PerThreadContext *p, AVPacket *avpkt) * and it calls back to the client here. */ - if (!p->avctx->thread_safe_callbacks && - p->avctx->get_buffer != avcodec_default_get_buffer) { + if (!p->avctx->thread_safe_callbacks && ( +#if FF_API_GET_BUFFER + p->avctx->get_buffer || +#endif + p->avctx->get_buffer2 != avcodec_default_get_buffer2)) { while (p->state != STATE_SETUP_FINISHED && p->state != STATE_INPUT_READY) { pthread_mutex_lock(&p->progress_mutex); while (p->state == STATE_SETTING_UP) pthread_cond_wait(&p->progress_cond, &p->progress_mutex); if (p->state == STATE_GET_BUFFER) { - p->result = ff_get_buffer(p->avctx, p->requested_frame); + p->result = ff_get_buffer(p->avctx, p->requested_frame, p->requested_flags); p->state = STATE_SETTING_UP; pthread_cond_signal(&p->progress_cond); } @@ -637,7 +631,7 @@ int ff_thread_decode_frame(AVCodecContext *avctx, pthread_mutex_unlock(&p->progress_mutex); } - *picture = p->frame; + av_frame_move_ref(picture, &p->frame); *got_picture_ptr = p->got_frame; picture->pkt_dts = p->avpkt.dts; @@ -662,10 +656,10 @@ int ff_thread_decode_frame(AVCodecContext *avctx, return (p->result >= 0) ? avpkt->size : p->result; } -void ff_thread_report_progress(AVFrame *f, int n, int field) +void ff_thread_report_progress(ThreadFrame *f, int n, int field) { PerThreadContext *p; - int *progress = f->thread_opaque; + int *progress = f->progress ? (int*)f->progress->data : NULL; if (!progress || progress[field] >= n) return; @@ -680,10 +674,10 @@ void ff_thread_report_progress(AVFrame *f, int n, int field) pthread_mutex_unlock(&p->progress_mutex); } -void ff_thread_await_progress(AVFrame *f, int n, int field) +void ff_thread_await_progress(ThreadFrame *f, int n, int field) { PerThreadContext *p; - int *progress = f->thread_opaque; + int *progress = f->progress ? (int*)f->progress->data : NULL; if (!progress || progress[field] >= n) return; @@ -760,8 +754,6 @@ static void frame_thread_free(AVCodecContext *avctx, int thread_count) for (i = 0; i < thread_count; i++) { PerThreadContext *p = &fctx->threads[i]; - avcodec_default_free_buffers(p->avctx); - pthread_mutex_destroy(&p->mutex); pthread_mutex_destroy(&p->progress_mutex); pthread_cond_destroy(&p->input_cond); @@ -769,6 +761,7 @@ static void frame_thread_free(AVCodecContext *avctx, int thread_count) pthread_cond_destroy(&p->output_cond); av_buffer_unref(&p->avpkt.buf); av_freep(&p->buf); + av_freep(&p->released_buffers); if (i) { av_freep(&p->avctx->priv_data); @@ -901,34 +894,15 @@ void ff_thread_flush(AVCodecContext *avctx) } } -static int *allocate_progress(PerThreadContext *p) -{ - int i; - - for (i = 0; i < MAX_BUFFERS; i++) - if (!p->progress_used[i]) break; - - if (i == MAX_BUFFERS) { - av_log(p->avctx, AV_LOG_ERROR, "allocate_progress() overflow\n"); - return NULL; - } - - p->progress_used[i] = 1; - - return p->progress[i]; -} - -int ff_thread_get_buffer(AVCodecContext *avctx, AVFrame *f) +int ff_thread_get_buffer(AVCodecContext *avctx, ThreadFrame *f, int flags) { PerThreadContext *p = avctx->thread_opaque; - int *progress, err; + int err; f->owner = avctx; - if (!(avctx->active_thread_type&FF_THREAD_FRAME)) { - f->thread_opaque = NULL; - return ff_get_buffer(avctx, f); - } + if (!(avctx->active_thread_type & FF_THREAD_FRAME)) + return ff_get_buffer(avctx, f->f, flags); if (p->state != STATE_SETTING_UP && (avctx->codec->update_thread_context || !avctx->thread_safe_callbacks)) { @@ -936,22 +910,27 @@ int ff_thread_get_buffer(AVCodecContext *avctx, AVFrame *f) return -1; } - pthread_mutex_lock(&p->parent->buffer_mutex); - f->thread_opaque = progress = allocate_progress(p); + if (avctx->internal->allocate_progress) { + int *progress; + f->progress = av_buffer_alloc(2 * sizeof(int)); + if (!f->progress) { + return AVERROR(ENOMEM); + } + progress = (int*)f->progress->data; - if (!progress) { - pthread_mutex_unlock(&p->parent->buffer_mutex); - return -1; + progress[0] = progress[1] = -1; } - progress[0] = - progress[1] = -1; - - if (avctx->thread_safe_callbacks || - avctx->get_buffer == avcodec_default_get_buffer) { - err = ff_get_buffer(avctx, f); + pthread_mutex_lock(&p->parent->buffer_mutex); + if (avctx->thread_safe_callbacks || ( +#if FF_API_GET_BUFFER + !avctx->get_buffer && +#endif + avctx->get_buffer2 == avcodec_default_get_buffer2)) { + err = ff_get_buffer(avctx, f->f, flags); } else { - p->requested_frame = f; + p->requested_frame = f->f; + p->requested_flags = flags; p->state = STATE_GET_BUFFER; pthread_mutex_lock(&p->progress_mutex); pthread_cond_signal(&p->progress_cond); @@ -967,41 +946,60 @@ int ff_thread_get_buffer(AVCodecContext *avctx, AVFrame *f) ff_thread_finish_setup(avctx); } - if (err) { - free_progress(f); - f->thread_opaque = NULL; - } + if (err) + av_buffer_unref(&f->progress); + pthread_mutex_unlock(&p->parent->buffer_mutex); return err; } -void ff_thread_release_buffer(AVCodecContext *avctx, AVFrame *f) +void ff_thread_release_buffer(AVCodecContext *avctx, ThreadFrame *f) { PerThreadContext *p = avctx->thread_opaque; FrameThreadContext *fctx; + AVFrame *dst, *tmp; + int can_direct_free = !(avctx->active_thread_type & FF_THREAD_FRAME) || + avctx->thread_safe_callbacks || + ( +#if FF_API_GET_BUFFER + !avctx->get_buffer && +#endif + avctx->get_buffer2 == avcodec_default_get_buffer2); - if (!f->data[0]) + if (!f->f->data[0]) return; - if (!(avctx->active_thread_type&FF_THREAD_FRAME)) { - avctx->release_buffer(avctx, f); - return; - } - - if (p->num_released_buffers >= MAX_BUFFERS) { - av_log(p->avctx, AV_LOG_ERROR, "too many thread_release_buffer calls!\n"); - return; - } - - if(avctx->debug & FF_DEBUG_BUFFERS) + if (avctx->debug & FF_DEBUG_BUFFERS) av_log(avctx, AV_LOG_DEBUG, "thread_release_buffer called on pic %p\n", f); + av_buffer_unref(&f->progress); + f->owner = NULL; + + if (can_direct_free) { + av_frame_unref(f->f); + return; + } + fctx = p->parent; pthread_mutex_lock(&fctx->buffer_mutex); - p->released_buffers[p->num_released_buffers++] = *f; + + if (p->num_released_buffers + 1 >= INT_MAX / sizeof(*p->released_buffers)) + goto fail; + tmp = av_fast_realloc(p->released_buffers, &p->released_buffers_allocated, + (p->num_released_buffers + 1) * + sizeof(*p->released_buffers)); + if (!tmp) + goto fail; + p->released_buffers = tmp; + + dst = &p->released_buffers[p->num_released_buffers]; + av_frame_move_ref(dst, f->f); + + p->num_released_buffers++; + +fail: pthread_mutex_unlock(&fctx->buffer_mutex); - memset(f->data, 0, sizeof(f->data)); } /** diff --git a/libavcodec/ptx.c b/libavcodec/ptx.c index e8f8bdd72c..f528843944 100644 --- a/libavcodec/ptx.c +++ b/libavcodec/ptx.c @@ -25,26 +25,11 @@ #include "avcodec.h" #include "internal.h" -typedef struct PTXContext { - AVFrame picture; -} PTXContext; - -static av_cold int ptx_init(AVCodecContext *avctx) { - PTXContext *s = avctx->priv_data; - - avcodec_get_frame_defaults(&s->picture); - avctx->coded_frame= &s->picture; - - return 0; -} - static int ptx_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { const uint8_t *buf = avpkt->data; const uint8_t *buf_end = avpkt->data + avpkt->size; - PTXContext * const s = avctx->priv_data; - AVFrame *picture = data; - AVFrame * const p = &s->picture; + AVFrame * const p = data; unsigned int offset, w, h, y, stride, bytes_per_pixel; int ret; uint8_t *ptr; @@ -70,14 +55,11 @@ static int ptx_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, buf += offset; - if (p->data[0]) - avctx->release_buffer(avctx, p); - if ((ret = av_image_check_size(w, h, 0, avctx)) < 0) return ret; if (w != avctx->width || h != avctx->height) avcodec_set_dimensions(avctx, w, h); - if ((ret = ff_get_buffer(avctx, p)) < 0) { + if ((ret = ff_get_buffer(avctx, p, 0)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } @@ -99,7 +81,6 @@ static int ptx_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, buf += w*bytes_per_pixel; } - *picture = s->picture; *got_frame = 1; if (y < h) { @@ -110,22 +91,10 @@ static int ptx_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, return offset + w*h*bytes_per_pixel; } -static av_cold int ptx_end(AVCodecContext *avctx) { - PTXContext *s = avctx->priv_data; - - if(s->picture.data[0]) - avctx->release_buffer(avctx, &s->picture); - - return 0; -} - AVCodec ff_ptx_decoder = { .name = "ptx", .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_PTX, - .priv_data_size = sizeof(PTXContext), - .init = ptx_init, - .close = ptx_end, .decode = ptx_decode_frame, .capabilities = CODEC_CAP_DR1, .long_name = NULL_IF_CONFIG_SMALL("V.Flash PTX image"), diff --git a/libavcodec/qcelpdec.c b/libavcodec/qcelpdec.c index 9c7855d78e..e7f2699138 100644 --- a/libavcodec/qcelpdec.c +++ b/libavcodec/qcelpdec.c @@ -695,7 +695,7 @@ static int qcelp_decode_frame(AVCodecContext *avctx, void *data, /* get output buffer */ frame->nb_samples = 160; - if ((ret = ff_get_buffer(avctx, frame)) < 0) { + if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } diff --git a/libavcodec/qdm2.c b/libavcodec/qdm2.c index 082a64f35e..91ef524ad6 100644 --- a/libavcodec/qdm2.c +++ b/libavcodec/qdm2.c @@ -1934,7 +1934,7 @@ static int qdm2_decode_frame(AVCodecContext *avctx, void *data, /* get output buffer */ frame->nb_samples = 16 * s->frame_size; - if ((ret = ff_get_buffer(avctx, frame)) < 0) { + if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } diff --git a/libavcodec/qdrw.c b/libavcodec/qdrw.c index 78ceca69ac..0dc72d0daa 100644 --- a/libavcodec/qdrw.c +++ b/libavcodec/qdrw.c @@ -29,11 +29,6 @@ #include "avcodec.h" #include "internal.h" -typedef struct QdrawContext { - AVCodecContext *avctx; - AVFrame pic; -} QdrawContext; - static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) @@ -41,26 +36,21 @@ static int decode_frame(AVCodecContext *avctx, const uint8_t *buf = avpkt->data; const uint8_t *buf_end = avpkt->data + avpkt->size; int buf_size = avpkt->size; - QdrawContext * const a = avctx->priv_data; - AVFrame * const p = &a->pic; + AVFrame * const p = data; uint8_t* outdata; int colors; int i, ret; uint32_t *pal; int r, g, b; - if (p->data[0]) - avctx->release_buffer(avctx, p); - - p->reference = 0; - if ((ret = ff_get_buffer(avctx, p)) < 0) { + if ((ret = ff_get_buffer(avctx, p, 0)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } p->pict_type = AV_PICTURE_TYPE_I; p->key_frame = 1; - outdata = a->pic.data[0]; + outdata = p->data[0]; if (buf_end - buf < 0x68 + 4) return AVERROR_INVALIDDATA; @@ -118,14 +108,14 @@ static int decode_frame(AVCodecContext *avctx, code = *buf++; if (code & 0x80 ) { /* run */ pix = *buf++; - if ((out + (257 - code)) > (outdata + a->pic.linesize[0])) + if ((out + (257 - code)) > (outdata + p->linesize[0])) break; memset(out, pix, 257 - code); out += 257 - code; tsize += 257 - code; left -= 2; } else { /* copy */ - if ((out + code) > (outdata + a->pic.linesize[0])) + if ((out + code) > (outdata + p->linesize[0])) break; if (buf_end - buf < code + 1) return AVERROR_INVALIDDATA; @@ -137,11 +127,10 @@ static int decode_frame(AVCodecContext *avctx, } } buf = next; - outdata += a->pic.linesize[0]; + outdata += p->linesize[0]; } *got_frame = 1; - *(AVFrame*)data = a->pic; return buf_size; } @@ -153,24 +142,11 @@ static av_cold int decode_init(AVCodecContext *avctx) return 0; } -static av_cold int decode_end(AVCodecContext *avctx) -{ - QdrawContext * const a = avctx->priv_data; - AVFrame *pic = &a->pic; - - if (pic->data[0]) - avctx->release_buffer(avctx, pic); - - return 0; -} - AVCodec ff_qdraw_decoder = { .name = "qdraw", .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_QDRAW, - .priv_data_size = sizeof(QdrawContext), .init = decode_init, - .close = decode_end, .decode = decode_frame, .capabilities = CODEC_CAP_DR1, .long_name = NULL_IF_CONFIG_SMALL("Apple QuickDraw"), diff --git a/libavcodec/qpeg.c b/libavcodec/qpeg.c index c295543c38..afcb2dfc97 100644 --- a/libavcodec/qpeg.c +++ b/libavcodec/qpeg.c @@ -26,6 +26,7 @@ #include "avcodec.h" #include "bytestream.h" +#include "internal.h" typedef struct QpegContext{ AVCodecContext *avctx; @@ -256,8 +257,7 @@ static int decode_frame(AVCodecContext *avctx, } bytestream2_init(&a->buffer, avpkt->data, avpkt->size); - p->reference = 3; - if ((ret = avctx->reget_buffer(avctx, p)) < 0) { + if ((ret = ff_reget_buffer(avctx, p)) < 0) { av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); return ret; } @@ -280,8 +280,10 @@ static int decode_frame(AVCodecContext *avctx, } memcpy(a->pic.data[1], a->pal, AVPALETTE_SIZE); + if ((ret = av_frame_ref(data, &a->pic)) < 0) + return ret; + *got_frame = 1; - *(AVFrame*)data = a->pic; return avpkt->size; } @@ -300,8 +302,7 @@ static av_cold int decode_end(AVCodecContext *avctx){ QpegContext * const a = avctx->priv_data; AVFrame * const p = &a->pic; - if(p->data[0]) - avctx->release_buffer(avctx, p); + av_frame_unref(p); av_free(a->refdata); return 0; diff --git a/libavcodec/qtrle.c b/libavcodec/qtrle.c index cc31592f01..7a1213f601 100644 --- a/libavcodec/qtrle.c +++ b/libavcodec/qtrle.c @@ -37,6 +37,7 @@ #include "avcodec.h" #include "bytestream.h" +#include "internal.h" typedef struct QtrleContext { AVCodecContext *avctx; @@ -400,10 +401,7 @@ static int qtrle_decode_frame(AVCodecContext *avctx, int ret; bytestream2_init(&s->g, avpkt->data, avpkt->size); - s->frame.reference = 1; - s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | - FF_BUFFER_HINTS_REUSABLE | FF_BUFFER_HINTS_READABLE; - if ((ret = avctx->reget_buffer(avctx, &s->frame)) < 0) { + if ((ret = ff_reget_buffer(avctx, &s->frame)) < 0) { av_log (s->avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); return ret; } @@ -487,8 +485,9 @@ static int qtrle_decode_frame(AVCodecContext *avctx, } done: + if ((ret = av_frame_ref(data, &s->frame)) < 0) + return ret; *got_frame = 1; - *(AVFrame*)data = s->frame; /* always report that the buffer was completely consumed */ return avpkt->size; @@ -498,8 +497,7 @@ static av_cold int qtrle_decode_end(AVCodecContext *avctx) { QtrleContext *s = avctx->priv_data; - if (s->frame.data[0]) - avctx->release_buffer(avctx, &s->frame); + av_frame_unref(&s->frame); return 0; } diff --git a/libavcodec/r210dec.c b/libavcodec/r210dec.c index 7fd663b9a3..35150d8602 100644 --- a/libavcodec/r210dec.c +++ b/libavcodec/r210dec.c @@ -30,8 +30,6 @@ static av_cold int decode_init(AVCodecContext *avctx) avctx->pix_fmt = AV_PIX_FMT_RGB48; avctx->bits_per_raw_sample = 10; - avctx->coded_frame = avcodec_alloc_frame(); - return 0; } @@ -39,21 +37,17 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { int h, w, ret; - AVFrame *pic = avctx->coded_frame; + AVFrame *pic = data; const uint32_t *src = (const uint32_t *)avpkt->data; int aligned_width = FFALIGN(avctx->width, 64); uint8_t *dst_line; - if (pic->data[0]) - avctx->release_buffer(avctx, pic); - if (avpkt->size < 4 * aligned_width * avctx->height) { av_log(avctx, AV_LOG_ERROR, "packet too small\n"); return AVERROR_INVALIDDATA; } - pic->reference = 0; - if ((ret = ff_get_buffer(avctx, pic)) < 0) + if ((ret = ff_get_buffer(avctx, pic, 0)) < 0) return ret; pic->pict_type = AV_PICTURE_TYPE_I; @@ -83,28 +77,16 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, } *got_frame = 1; - *(AVFrame*)data = *avctx->coded_frame; return avpkt->size; } -static av_cold int decode_close(AVCodecContext *avctx) -{ - AVFrame *pic = avctx->coded_frame; - if (pic->data[0]) - avctx->release_buffer(avctx, pic); - av_freep(&avctx->coded_frame); - - return 0; -} - #if CONFIG_R210_DECODER AVCodec ff_r210_decoder = { .name = "r210", .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_R210, .init = decode_init, - .close = decode_close, .decode = decode_frame, .capabilities = CODEC_CAP_DR1, .long_name = NULL_IF_CONFIG_SMALL("Uncompressed RGB 10-bit"), @@ -116,7 +98,6 @@ AVCodec ff_r10k_decoder = { .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_R10K, .init = decode_init, - .close = decode_close, .decode = decode_frame, .capabilities = CODEC_CAP_DR1, .long_name = NULL_IF_CONFIG_SMALL("AJA Kona 10-bit RGB Codec"), diff --git a/libavcodec/ra144dec.c b/libavcodec/ra144dec.c index d3c81ca6a1..e2d116c201 100644 --- a/libavcodec/ra144dec.c +++ b/libavcodec/ra144dec.c @@ -78,7 +78,7 @@ static int ra144_decode_frame(AVCodecContext * avctx, void *data, /* get output buffer */ frame->nb_samples = NBLOCKS * BLOCKSIZE; - if ((ret = ff_get_buffer(avctx, frame)) < 0) { + if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } diff --git a/libavcodec/ra288.c b/libavcodec/ra288.c index 744824ba6b..5cccbe9a0c 100644 --- a/libavcodec/ra288.c +++ b/libavcodec/ra288.c @@ -191,7 +191,7 @@ static int ra288_decode_frame(AVCodecContext * avctx, void *data, /* get output buffer */ frame->nb_samples = RA288_BLOCK_SIZE * RA288_BLOCKS_PER_FRAME; - if ((ret = ff_get_buffer(avctx, frame)) < 0) { + if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } diff --git a/libavcodec/ralf.c b/libavcodec/ralf.c index b163a895ab..91c984f083 100644 --- a/libavcodec/ralf.c +++ b/libavcodec/ralf.c @@ -460,7 +460,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame_ptr, } frame->nb_samples = ctx->max_frame_size; - if ((ret = ff_get_buffer(avctx, frame)) < 0) { + if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) { av_log(avctx, AV_LOG_ERROR, "Me fail get_buffer()? That's unpossible!\n"); return ret; } diff --git a/libavcodec/rawdec.c b/libavcodec/rawdec.c index ab93d49e07..59a6dd676d 100644 --- a/libavcodec/rawdec.c +++ b/libavcodec/rawdec.c @@ -26,16 +26,17 @@ #include "avcodec.h" #include "raw.h" +#include "libavutil/buffer.h" #include "libavutil/common.h" #include "libavutil/intreadwrite.h" #include "libavutil/imgutils.h" typedef struct RawVideoContext { - uint32_t palette[AVPALETTE_COUNT]; - unsigned char *buffer; /* block of memory for holding one frame */ - int length; /* number of bytes in buffer */ + AVBufferRef *palette; + int frame_size; /* size of the frame in bytes */ int flip; - AVFrame pic; ///< AVCodecContext.coded_frame + int is_2_4_bpp; // 2 or 4 bpp raw in avi/mov + int is_yuv2; } RawVideoContext; static const PixelFormatTag pix_fmt_bps_avi[] = { @@ -77,6 +78,7 @@ static enum AVPixelFormat find_pix_fmt(const PixelFormatTag *tags, static av_cold int raw_init_decoder(AVCodecContext *avctx) { RawVideoContext *context = avctx->priv_data; + const AVPixFmtDescriptor *desc; if (avctx->codec_tag == MKTAG('r', 'a', 'w', ' ')) avctx->pix_fmt = find_pix_fmt(pix_fmt_bps_mov, @@ -90,20 +92,28 @@ static av_cold int raw_init_decoder(AVCodecContext *avctx) avctx->pix_fmt = find_pix_fmt(pix_fmt_bps_avi, avctx->bits_per_coded_sample); - avpriv_set_systematic_pal2(context->palette, avctx->pix_fmt); - context->length = avpicture_get_size(avctx->pix_fmt, avctx->width, - avctx->height); + desc = av_pix_fmt_desc_get(avctx->pix_fmt); + if (!desc) { + av_log(avctx, AV_LOG_ERROR, "Invalid pixel format.\n"); + return AVERROR(EINVAL); + } + + if (desc->flags & (PIX_FMT_PAL || PIX_FMT_PSEUDOPAL)) { + context->palette = av_buffer_alloc(AVPALETTE_SIZE); + if (!context->palette) + return AVERROR(ENOMEM); + if (desc->flags & PIX_FMT_PSEUDOPAL) + avpriv_set_systematic_pal2((uint32_t*)context->palette->data, avctx->pix_fmt); + else + memset(context->palette->data, 0, AVPALETTE_SIZE); + } + + context->frame_size = avpicture_get_size(avctx->pix_fmt, avctx->width, + avctx->height); if ((avctx->bits_per_coded_sample == 4 || avctx->bits_per_coded_sample == 2) && avctx->pix_fmt == AV_PIX_FMT_PAL8 && - (!avctx->codec_tag || avctx->codec_tag == MKTAG('r','a','w',' '))) { - context->buffer = av_malloc(context->length); - if (!context->buffer) - return -1; - } - context->pic.pict_type = AV_PICTURE_TYPE_I; - context->pic.key_frame = 1; - - avctx->coded_frame = &context->pic; + (!avctx->codec_tag || avctx->codec_tag == MKTAG('r','a','w',' '))) + context->is_2_4_bpp = 1; if ((avctx->extradata_size >= 9 && !memcmp(avctx->extradata + avctx->extradata_size - 9, "BottomUp", 9)) || @@ -111,6 +121,10 @@ static av_cold int raw_init_decoder(AVCodecContext *avctx) avctx->codec_tag == MKTAG('W','R','A','W')) context->flip = 1; + if (avctx->codec_tag == AV_RL32("yuv2") && + avctx->pix_fmt == AV_PIX_FMT_YUYV422) + context->is_yuv2 = 1; + return 0; } @@ -127,26 +141,33 @@ static int raw_decode(AVCodecContext *avctx, void *data, int *got_frame, RawVideoContext *context = avctx->priv_data; const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; + int need_copy = !avpkt->buf || context->is_2_4_bpp || context->is_yuv2; int res; AVFrame *frame = data; AVPicture *picture = data; - frame->pict_type = avctx->coded_frame->pict_type; - frame->interlaced_frame = avctx->coded_frame->interlaced_frame; - frame->top_field_first = avctx->coded_frame->top_field_first; + frame->pict_type = AV_PICTURE_TYPE_I; + frame->key_frame = 1; frame->reordered_opaque = avctx->reordered_opaque; frame->pkt_pts = avctx->pkt->pts; - if (buf_size < context->length - (avctx->pix_fmt == AV_PIX_FMT_PAL8 ? - AVPALETTE_SIZE : 0)) + if (buf_size < context->frame_size - (avctx->pix_fmt == AV_PIX_FMT_PAL8 ? + AVPALETTE_SIZE : 0)) return -1; + if (need_copy) + frame->buf[0] = av_buffer_alloc(context->frame_size); + else + frame->buf[0] = av_buffer_ref(avpkt->buf); + if (!frame->buf[0]) + return AVERROR(ENOMEM); + //2bpp and 4bpp raw in avi and mov (yes this is ugly ...) - if (context->buffer) { + if (context->is_2_4_bpp) { int i; - uint8_t *dst = context->buffer; - buf_size = context->length - AVPALETTE_SIZE; + uint8_t *dst = frame->buf[0]->data; + buf_size = context->frame_size - AVPALETTE_SIZE; if (avctx->bits_per_coded_sample == 4) { for (i = 0; 2 * i + 1 < buf_size; i++) { dst[2 * i + 0] = buf[i] >> 4; @@ -161,28 +182,40 @@ static int raw_decode(AVCodecContext *avctx, void *data, int *got_frame, } } buf = dst; + } else if (need_copy) { + memcpy(frame->buf[0]->data, buf, FFMIN(buf_size, context->frame_size)); + buf = frame->buf[0]->data; } if (avctx->codec_tag == MKTAG('A', 'V', '1', 'x') || avctx->codec_tag == MKTAG('A', 'V', 'u', 'p')) - buf += buf_size - context->length; + buf += buf_size - context->frame_size; if ((res = avpicture_fill(picture, buf, avctx->pix_fmt, avctx->width, avctx->height)) < 0) return res; - if ((avctx->pix_fmt == AV_PIX_FMT_PAL8 && buf_size < context->length) || - (desc->flags & PIX_FMT_PSEUDOPAL)) { - frame->data[1] = context->palette; - } + if (avctx->pix_fmt == AV_PIX_FMT_PAL8) { const uint8_t *pal = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE, NULL); if (pal) { - memcpy(frame->data[1], pal, AVPALETTE_SIZE); + av_buffer_unref(&context->palette); + context->palette = av_buffer_alloc(AVPALETTE_SIZE); + if (!context->palette) + return AVERROR(ENOMEM); + memcpy(context->palette->data, pal, AVPALETTE_SIZE); frame->palette_has_changed = 1; } } + + if ((avctx->pix_fmt == AV_PIX_FMT_PAL8 && buf_size < context->frame_size) || + (desc->flags & PIX_FMT_PSEUDOPAL)) { + frame->buf[1] = av_buffer_ref(context->palette); + if (!frame->buf[1]) + return AVERROR(ENOMEM); + frame->data[1] = frame->buf[1]->data; + } if (avctx->pix_fmt == AV_PIX_FMT_BGR24 && ((frame->linesize[0] + 3) & ~3) * avctx->height <= buf_size) frame->linesize[0] = (frame->linesize[0] + 3) & ~3; @@ -215,7 +248,7 @@ static av_cold int raw_close_decoder(AVCodecContext *avctx) { RawVideoContext *context = avctx->priv_data; - av_freep(&context->buffer); + av_buffer_unref(&context->palette); return 0; } diff --git a/libavcodec/rl2.c b/libavcodec/rl2.c index 9973c28736..4f68f7e997 100644 --- a/libavcodec/rl2.c +++ b/libavcodec/rl2.c @@ -41,7 +41,6 @@ typedef struct Rl2Context { AVCodecContext *avctx; - AVFrame frame; uint16_t video_base; ///< initial drawing offset uint32_t clr_count; ///< number of used colors (currently unused) @@ -177,29 +176,24 @@ static int rl2_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { + AVFrame *frame = data; const uint8_t *buf = avpkt->data; int ret, buf_size = avpkt->size; Rl2Context *s = avctx->priv_data; - if (s->frame.data[0]) - avctx->release_buffer(avctx, &s->frame); - - /** get buffer */ - s->frame.reference = 0; - if ((ret = ff_get_buffer(avctx, &s->frame)) < 0) { + if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) { av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } /** run length decode */ - rl2_rle_decode(s, buf, buf_size, s->frame.data[0], s->frame.linesize[0], + rl2_rle_decode(s, buf, buf_size, frame->data[0], frame->linesize[0], s->video_base); /** make the palette available on the way out */ - memcpy(s->frame.data[1], s->palette, AVPALETTE_SIZE); + memcpy(frame->data[1], s->palette, AVPALETTE_SIZE); *got_frame = 1; - *(AVFrame*)data = s->frame; /** report that the buffer was completely consumed */ return buf_size; @@ -215,9 +209,6 @@ static av_cold int rl2_decode_end(AVCodecContext *avctx) { Rl2Context *s = avctx->priv_data; - if (s->frame.data[0]) - avctx->release_buffer(avctx, &s->frame); - av_free(s->back_frame); return 0; diff --git a/libavcodec/roqvideodec.c b/libavcodec/roqvideodec.c index 3ee62c01b5..ef561a3210 100644 --- a/libavcodec/roqvideodec.c +++ b/libavcodec/roqvideodec.c @@ -31,6 +31,7 @@ #include "avcodec.h" #include "bytestream.h" +#include "internal.h" #include "roqvideo.h" static void roqvideo_decode_frame(RoqContext *ri) @@ -168,8 +169,15 @@ static av_cold int roq_decode_init(AVCodecContext *avctx) s->width = avctx->width; s->height = avctx->height; - s->last_frame = &s->frames[0]; - s->current_frame = &s->frames[1]; + + s->last_frame = av_frame_alloc(); + s->current_frame = av_frame_alloc(); + if (!s->current_frame || !s->last_frame) { + av_frame_free(&s->current_frame); + av_frame_free(&s->last_frame); + return AVERROR(ENOMEM); + } + avctx->pix_fmt = AV_PIX_FMT_YUV444P; return 0; @@ -183,11 +191,11 @@ static int roq_decode_frame(AVCodecContext *avctx, int buf_size = avpkt->size; RoqContext *s = avctx->priv_data; int copy= !s->current_frame->data[0]; + int ret; - s->current_frame->reference = 3; - if (avctx->reget_buffer(avctx, s->current_frame)) { + if ((ret = ff_reget_buffer(avctx, s->current_frame)) < 0) { av_log(avctx, AV_LOG_ERROR, " RoQ: get_buffer() failed\n"); - return -1; + return ret; } if(copy) @@ -197,8 +205,9 @@ static int roq_decode_frame(AVCodecContext *avctx, bytestream2_init(&s->gb, buf, buf_size); roqvideo_decode_frame(s); + if ((ret = av_frame_ref(data, s->current_frame)) < 0) + return ret; *got_frame = 1; - *(AVFrame*)data = *s->current_frame; /* shuffle frames */ FFSWAP(AVFrame *, s->current_frame, s->last_frame); @@ -210,11 +219,8 @@ static av_cold int roq_decode_end(AVCodecContext *avctx) { RoqContext *s = avctx->priv_data; - /* release the last frame */ - if (s->last_frame->data[0]) - avctx->release_buffer(avctx, s->last_frame); - if (s->current_frame->data[0]) - avctx->release_buffer(avctx, s->current_frame); + av_frame_free(&s->current_frame); + av_frame_free(&s->last_frame); return 0; } diff --git a/libavcodec/roqvideoenc.c b/libavcodec/roqvideoenc.c index 192f1eb6a3..636418a5d9 100644 --- a/libavcodec/roqvideoenc.c +++ b/libavcodec/roqvideoenc.c @@ -936,6 +936,22 @@ static void roq_encode_video(RoqContext *enc) enc->framesSinceKeyframe++; } +static int roq_encode_end(AVCodecContext *avctx) +{ + RoqContext *enc = avctx->priv_data; + + av_frame_free(&enc->current_frame); + av_frame_free(&enc->last_frame); + + av_free(enc->tmpData); + av_free(enc->this_motion4); + av_free(enc->last_motion4); + av_free(enc->this_motion8); + av_free(enc->last_motion8); + + return 0; +} + static int roq_encode_init(AVCodecContext *avctx) { RoqContext *enc = avctx->priv_data; @@ -957,8 +973,12 @@ static int roq_encode_init(AVCodecContext *avctx) enc->framesSinceKeyframe = 0; enc->first_frame = 1; - enc->last_frame = &enc->frames[0]; - enc->current_frame = &enc->frames[1]; + enc->last_frame = av_frame_alloc(); + enc->current_frame = av_frame_alloc(); + if (!enc->last_frame || !enc->current_frame) { + roq_encode_end(avctx); + return AVERROR(ENOMEM); + } enc->tmpData = av_malloc(sizeof(RoqTempdata)); @@ -1033,8 +1053,8 @@ static int roq_encode_frame(AVCodecContext *avctx, AVPacket *pkt, if (enc->first_frame) { /* Alloc memory for the reconstruction data (we must know the stride for that) */ - if (ff_get_buffer(avctx, enc->current_frame) || - ff_get_buffer(avctx, enc->last_frame)) { + if (ff_get_buffer(avctx, enc->current_frame, 0) || + ff_get_buffer(avctx, enc->last_frame, 0)) { av_log(avctx, AV_LOG_ERROR, " RoQ: get_buffer() failed\n"); return -1; } @@ -1056,22 +1076,6 @@ static int roq_encode_frame(AVCodecContext *avctx, AVPacket *pkt, return 0; } -static int roq_encode_end(AVCodecContext *avctx) -{ - RoqContext *enc = avctx->priv_data; - - avctx->release_buffer(avctx, enc->last_frame); - avctx->release_buffer(avctx, enc->current_frame); - - av_free(enc->tmpData); - av_free(enc->this_motion4); - av_free(enc->last_motion4); - av_free(enc->this_motion8); - av_free(enc->last_motion8); - - return 0; -} - AVCodec ff_roq_encoder = { .name = "roqvideo", .type = AVMEDIA_TYPE_VIDEO, diff --git a/libavcodec/rpza.c b/libavcodec/rpza.c index ee36607393..dd2b547afc 100644 --- a/libavcodec/rpza.c +++ b/libavcodec/rpza.c @@ -41,6 +41,7 @@ #include "libavutil/internal.h" #include "libavutil/intreadwrite.h" #include "avcodec.h" +#include "internal.h" typedef struct RpzaContext { @@ -255,17 +256,17 @@ static int rpza_decode_frame(AVCodecContext *avctx, s->buf = buf; s->size = buf_size; - s->frame.reference = 1; - s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE; - if ((ret = avctx->reget_buffer(avctx, &s->frame)) < 0) { + if ((ret = ff_reget_buffer(avctx, &s->frame)) < 0) { av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); return ret; } rpza_decode_stream(s); + if ((ret = av_frame_ref(data, &s->frame)) < 0) + return ret; + *got_frame = 1; - *(AVFrame*)data = s->frame; /* always report that the buffer was completely consumed */ return buf_size; @@ -275,8 +276,7 @@ static av_cold int rpza_decode_end(AVCodecContext *avctx) { RpzaContext *s = avctx->priv_data; - if (s->frame.data[0]) - avctx->release_buffer(avctx, &s->frame); + av_frame_unref(&s->frame); return 0; } diff --git a/libavcodec/rv10.c b/libavcodec/rv10.c index c3e977a760..7fd4ddfa42 100644 --- a/libavcodec/rv10.c +++ b/libavcodec/rv10.c @@ -644,7 +644,7 @@ static int rv10_decode_frame(AVCodecContext *avctx, const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; MpegEncContext *s = avctx->priv_data; - int i; + int i, ret; AVFrame *pict = data; int slice_count; const uint8_t *slices_hdr = NULL; @@ -701,14 +701,17 @@ static int rv10_decode_frame(AVCodecContext *avctx, ff_MPV_frame_end(s); if (s->pict_type == AV_PICTURE_TYPE_B || s->low_delay) { - *pict = s->current_picture_ptr->f; + if ((ret = av_frame_ref(pict, &s->current_picture_ptr->f)) < 0) + return ret; + ff_print_debug_info(s, s->current_picture_ptr); } else if (s->last_picture_ptr != NULL) { - *pict = s->last_picture_ptr->f; + if ((ret = av_frame_ref(pict, &s->last_picture_ptr->f)) < 0) + return ret; + ff_print_debug_info(s, s->last_picture_ptr); } if(s->last_picture_ptr || s->low_delay){ *got_frame = 1; - ff_print_debug_info(s, pict); } s->current_picture_ptr= NULL; // so we can detect if frame_end was not called (find some nicer solution...) } diff --git a/libavcodec/rv30.c b/libavcodec/rv30.c index ae99a823bf..32f523b431 100644 --- a/libavcodec/rv30.c +++ b/libavcodec/rv30.c @@ -141,7 +141,7 @@ static void rv30_loop_filter(RV34DecContext *r, int row) mb_pos = row * s->mb_stride; for(mb_x = 0; mb_x < s->mb_width; mb_x++, mb_pos++){ - int mbtype = s->current_picture_ptr->f.mb_type[mb_pos]; + int mbtype = s->current_picture_ptr->mb_type[mb_pos]; if(IS_INTRA(mbtype) || IS_SEPARATE_DC(mbtype)) r->deblock_coefs[mb_pos] = 0xFFFF; if(IS_INTRA(mbtype)) @@ -153,9 +153,9 @@ static void rv30_loop_filter(RV34DecContext *r, int row) */ mb_pos = row * s->mb_stride; for(mb_x = 0; mb_x < s->mb_width; mb_x++, mb_pos++){ - cur_lim = rv30_loop_filt_lim[s->current_picture_ptr->f.qscale_table[mb_pos]]; + cur_lim = rv30_loop_filt_lim[s->current_picture_ptr->qscale_table[mb_pos]]; if(mb_x) - left_lim = rv30_loop_filt_lim[s->current_picture_ptr->f.qscale_table[mb_pos - 1]]; + left_lim = rv30_loop_filt_lim[s->current_picture_ptr->qscale_table[mb_pos - 1]]; for(j = 0; j < 16; j += 4){ Y = s->current_picture_ptr->f.data[0] + mb_x*16 + (row*16 + j) * s->linesize + 4 * !mb_x; for(i = !mb_x; i < 4; i++, Y += 4){ @@ -195,9 +195,9 @@ static void rv30_loop_filter(RV34DecContext *r, int row) } mb_pos = row * s->mb_stride; for(mb_x = 0; mb_x < s->mb_width; mb_x++, mb_pos++){ - cur_lim = rv30_loop_filt_lim[s->current_picture_ptr->f.qscale_table[mb_pos]]; + cur_lim = rv30_loop_filt_lim[s->current_picture_ptr->qscale_table[mb_pos]]; if(row) - top_lim = rv30_loop_filt_lim[s->current_picture_ptr->f.qscale_table[mb_pos - s->mb_stride]]; + top_lim = rv30_loop_filt_lim[s->current_picture_ptr->qscale_table[mb_pos - s->mb_stride]]; for(j = 4*!row; j < 16; j += 4){ Y = s->current_picture_ptr->f.data[0] + mb_x*16 + (row*16 + j) * s->linesize; for(i = 0; i < 4; i++, Y += 4){ diff --git a/libavcodec/rv34.c b/libavcodec/rv34.c index bd64a4be7c..aedf417da4 100644 --- a/libavcodec/rv34.c +++ b/libavcodec/rv34.c @@ -357,7 +357,7 @@ static int rv34_decode_intra_mb_header(RV34DecContext *r, int8_t *intra_types) r->is16 = get_bits1(gb); if(r->is16){ - s->current_picture_ptr->f.mb_type[mb_pos] = MB_TYPE_INTRA16x16; + s->current_picture_ptr->mb_type[mb_pos] = MB_TYPE_INTRA16x16; r->block_type = RV34_MB_TYPE_INTRA16x16; t = get_bits(gb, 2); fill_rectangle(intra_types, 4, 4, r->intra_types_stride, t, sizeof(intra_types[0])); @@ -367,7 +367,7 @@ static int rv34_decode_intra_mb_header(RV34DecContext *r, int8_t *intra_types) if(!get_bits1(gb)) av_log(s->avctx, AV_LOG_ERROR, "Need DQUANT\n"); } - s->current_picture_ptr->f.mb_type[mb_pos] = MB_TYPE_INTRA; + s->current_picture_ptr->mb_type[mb_pos] = MB_TYPE_INTRA; r->block_type = RV34_MB_TYPE_INTRA; if(r->decode_intra_types(r, gb, intra_types) < 0) return -1; @@ -393,7 +393,7 @@ static int rv34_decode_inter_mb_header(RV34DecContext *r, int8_t *intra_types) r->block_type = r->decode_mb_info(r); if(r->block_type == -1) return -1; - s->current_picture_ptr->f.mb_type[mb_pos] = rv34_mb_type_to_lavc[r->block_type]; + s->current_picture_ptr->mb_type[mb_pos] = rv34_mb_type_to_lavc[r->block_type]; r->mb_type[mb_pos] = r->block_type; if(r->block_type == RV34_MB_SKIP){ if(s->pict_type == AV_PICTURE_TYPE_P) @@ -401,7 +401,7 @@ static int rv34_decode_inter_mb_header(RV34DecContext *r, int8_t *intra_types) if(s->pict_type == AV_PICTURE_TYPE_B) r->mb_type[mb_pos] = RV34_MB_B_DIRECT; } - r->is16 = !!IS_INTRA16x16(s->current_picture_ptr->f.mb_type[mb_pos]); + r->is16 = !!IS_INTRA16x16(s->current_picture_ptr->mb_type[mb_pos]); rv34_decode_mv(r, r->block_type); if(r->block_type == RV34_MB_SKIP){ fill_rectangle(intra_types, 4, 4, r->intra_types_stride, 0, sizeof(intra_types[0])); @@ -410,7 +410,7 @@ static int rv34_decode_inter_mb_header(RV34DecContext *r, int8_t *intra_types) r->chroma_vlc = 1; r->luma_vlc = 0; - if(IS_INTRA(s->current_picture_ptr->f.mb_type[mb_pos])){ + if(IS_INTRA(s->current_picture_ptr->mb_type[mb_pos])){ if(r->is16){ t = get_bits(gb, 2); fill_rectangle(intra_types, 4, 4, r->intra_types_stride, t, sizeof(intra_types[0])); @@ -475,27 +475,27 @@ static void rv34_pred_mv(RV34DecContext *r, int block_type, int subblock_no, int c_off = -1; if(avail[-1]){ - A[0] = s->current_picture_ptr->f.motion_val[0][mv_pos-1][0]; - A[1] = s->current_picture_ptr->f.motion_val[0][mv_pos-1][1]; + A[0] = s->current_picture_ptr->motion_val[0][mv_pos-1][0]; + A[1] = s->current_picture_ptr->motion_val[0][mv_pos-1][1]; } if(avail[-4]){ - B[0] = s->current_picture_ptr->f.motion_val[0][mv_pos-s->b8_stride][0]; - B[1] = s->current_picture_ptr->f.motion_val[0][mv_pos-s->b8_stride][1]; + B[0] = s->current_picture_ptr->motion_val[0][mv_pos-s->b8_stride][0]; + B[1] = s->current_picture_ptr->motion_val[0][mv_pos-s->b8_stride][1]; }else{ B[0] = A[0]; B[1] = A[1]; } if(!avail[c_off-4]){ if(avail[-4] && (avail[-1] || r->rv30)){ - C[0] = s->current_picture_ptr->f.motion_val[0][mv_pos-s->b8_stride-1][0]; - C[1] = s->current_picture_ptr->f.motion_val[0][mv_pos-s->b8_stride-1][1]; + C[0] = s->current_picture_ptr->motion_val[0][mv_pos-s->b8_stride-1][0]; + C[1] = s->current_picture_ptr->motion_val[0][mv_pos-s->b8_stride-1][1]; }else{ C[0] = A[0]; C[1] = A[1]; } }else{ - C[0] = s->current_picture_ptr->f.motion_val[0][mv_pos-s->b8_stride+c_off][0]; - C[1] = s->current_picture_ptr->f.motion_val[0][mv_pos-s->b8_stride+c_off][1]; + C[0] = s->current_picture_ptr->motion_val[0][mv_pos-s->b8_stride+c_off][0]; + C[1] = s->current_picture_ptr->motion_val[0][mv_pos-s->b8_stride+c_off][1]; } mx = mid_pred(A[0], B[0], C[0]); my = mid_pred(A[1], B[1], C[1]); @@ -503,8 +503,8 @@ static void rv34_pred_mv(RV34DecContext *r, int block_type, int subblock_no, int my += r->dmv[dmv_no][1]; for(j = 0; j < part_sizes_h[block_type]; j++){ for(i = 0; i < part_sizes_w[block_type]; i++){ - s->current_picture_ptr->f.motion_val[0][mv_pos + i + j*s->b8_stride][0] = mx; - s->current_picture_ptr->f.motion_val[0][mv_pos + i + j*s->b8_stride][1] = my; + s->current_picture_ptr->motion_val[0][mv_pos + i + j*s->b8_stride][0] = mx; + s->current_picture_ptr->motion_val[0][mv_pos + i + j*s->b8_stride][1] = my; } } } @@ -555,25 +555,25 @@ static void rv34_pred_mv_b(RV34DecContext *r, int block_type, int dir) int i, j; Picture *cur_pic = s->current_picture_ptr; const int mask = dir ? MB_TYPE_L1 : MB_TYPE_L0; - int type = cur_pic->f.mb_type[mb_pos]; + int type = cur_pic->mb_type[mb_pos]; if((r->avail_cache[6-1] & type) & mask){ - A[0] = cur_pic->f.motion_val[dir][mv_pos - 1][0]; - A[1] = cur_pic->f.motion_val[dir][mv_pos - 1][1]; + A[0] = cur_pic->motion_val[dir][mv_pos - 1][0]; + A[1] = cur_pic->motion_val[dir][mv_pos - 1][1]; has_A = 1; } if((r->avail_cache[6-4] & type) & mask){ - B[0] = cur_pic->f.motion_val[dir][mv_pos - s->b8_stride][0]; - B[1] = cur_pic->f.motion_val[dir][mv_pos - s->b8_stride][1]; + B[0] = cur_pic->motion_val[dir][mv_pos - s->b8_stride][0]; + B[1] = cur_pic->motion_val[dir][mv_pos - s->b8_stride][1]; has_B = 1; } if(r->avail_cache[6-4] && (r->avail_cache[6-2] & type) & mask){ - C[0] = cur_pic->f.motion_val[dir][mv_pos - s->b8_stride + 2][0]; - C[1] = cur_pic->f.motion_val[dir][mv_pos - s->b8_stride + 2][1]; + C[0] = cur_pic->motion_val[dir][mv_pos - s->b8_stride + 2][0]; + C[1] = cur_pic->motion_val[dir][mv_pos - s->b8_stride + 2][1]; has_C = 1; }else if((s->mb_x+1) == s->mb_width && (r->avail_cache[6-5] & type) & mask){ - C[0] = cur_pic->f.motion_val[dir][mv_pos - s->b8_stride - 1][0]; - C[1] = cur_pic->f.motion_val[dir][mv_pos - s->b8_stride - 1][1]; + C[0] = cur_pic->motion_val[dir][mv_pos - s->b8_stride - 1][0]; + C[1] = cur_pic->motion_val[dir][mv_pos - s->b8_stride - 1][1]; has_C = 1; } @@ -584,12 +584,12 @@ static void rv34_pred_mv_b(RV34DecContext *r, int block_type, int dir) for(j = 0; j < 2; j++){ for(i = 0; i < 2; i++){ - cur_pic->f.motion_val[dir][mv_pos + i + j*s->b8_stride][0] = mx; - cur_pic->f.motion_val[dir][mv_pos + i + j*s->b8_stride][1] = my; + cur_pic->motion_val[dir][mv_pos + i + j*s->b8_stride][0] = mx; + cur_pic->motion_val[dir][mv_pos + i + j*s->b8_stride][1] = my; } } if(block_type == RV34_MB_B_BACKWARD || block_type == RV34_MB_B_FORWARD){ - ZERO8x2(cur_pic->f.motion_val[!dir][mv_pos], s->b8_stride); + ZERO8x2(cur_pic->motion_val[!dir][mv_pos], s->b8_stride); } } @@ -606,27 +606,27 @@ static void rv34_pred_mv_rv3(RV34DecContext *r, int block_type, int dir) int* avail = r->avail_cache + avail_indexes[0]; if(avail[-1]){ - A[0] = s->current_picture_ptr->f.motion_val[0][mv_pos - 1][0]; - A[1] = s->current_picture_ptr->f.motion_val[0][mv_pos - 1][1]; + A[0] = s->current_picture_ptr->motion_val[0][mv_pos - 1][0]; + A[1] = s->current_picture_ptr->motion_val[0][mv_pos - 1][1]; } if(avail[-4]){ - B[0] = s->current_picture_ptr->f.motion_val[0][mv_pos - s->b8_stride][0]; - B[1] = s->current_picture_ptr->f.motion_val[0][mv_pos - s->b8_stride][1]; + B[0] = s->current_picture_ptr->motion_val[0][mv_pos - s->b8_stride][0]; + B[1] = s->current_picture_ptr->motion_val[0][mv_pos - s->b8_stride][1]; }else{ B[0] = A[0]; B[1] = A[1]; } if(!avail[-4 + 2]){ if(avail[-4] && (avail[-1])){ - C[0] = s->current_picture_ptr->f.motion_val[0][mv_pos - s->b8_stride - 1][0]; - C[1] = s->current_picture_ptr->f.motion_val[0][mv_pos - s->b8_stride - 1][1]; + C[0] = s->current_picture_ptr->motion_val[0][mv_pos - s->b8_stride - 1][0]; + C[1] = s->current_picture_ptr->motion_val[0][mv_pos - s->b8_stride - 1][1]; }else{ C[0] = A[0]; C[1] = A[1]; } }else{ - C[0] = s->current_picture_ptr->f.motion_val[0][mv_pos - s->b8_stride + 2][0]; - C[1] = s->current_picture_ptr->f.motion_val[0][mv_pos - s->b8_stride + 2][1]; + C[0] = s->current_picture_ptr->motion_val[0][mv_pos - s->b8_stride + 2][0]; + C[1] = s->current_picture_ptr->motion_val[0][mv_pos - s->b8_stride + 2][1]; } mx = mid_pred(A[0], B[0], C[0]); my = mid_pred(A[1], B[1], C[1]); @@ -635,8 +635,8 @@ static void rv34_pred_mv_rv3(RV34DecContext *r, int block_type, int dir) for(j = 0; j < 2; j++){ for(i = 0; i < 2; i++){ for(k = 0; k < 2; k++){ - s->current_picture_ptr->f.motion_val[k][mv_pos + i + j*s->b8_stride][0] = mx; - s->current_picture_ptr->f.motion_val[k][mv_pos + i + j*s->b8_stride][1] = my; + s->current_picture_ptr->motion_val[k][mv_pos + i + j*s->b8_stride][0] = mx; + s->current_picture_ptr->motion_val[k][mv_pos + i + j*s->b8_stride][1] = my; } } } @@ -674,24 +674,24 @@ static inline void rv34_mc(RV34DecContext *r, const int block_type, if(thirdpel){ int chroma_mx, chroma_my; - mx = (s->current_picture_ptr->f.motion_val[dir][mv_pos][0] + (3 << 24)) / 3 - (1 << 24); - my = (s->current_picture_ptr->f.motion_val[dir][mv_pos][1] + (3 << 24)) / 3 - (1 << 24); - lx = (s->current_picture_ptr->f.motion_val[dir][mv_pos][0] + (3 << 24)) % 3; - ly = (s->current_picture_ptr->f.motion_val[dir][mv_pos][1] + (3 << 24)) % 3; - chroma_mx = s->current_picture_ptr->f.motion_val[dir][mv_pos][0] / 2; - chroma_my = s->current_picture_ptr->f.motion_val[dir][mv_pos][1] / 2; + mx = (s->current_picture_ptr->motion_val[dir][mv_pos][0] + (3 << 24)) / 3 - (1 << 24); + my = (s->current_picture_ptr->motion_val[dir][mv_pos][1] + (3 << 24)) / 3 - (1 << 24); + lx = (s->current_picture_ptr->motion_val[dir][mv_pos][0] + (3 << 24)) % 3; + ly = (s->current_picture_ptr->motion_val[dir][mv_pos][1] + (3 << 24)) % 3; + chroma_mx = s->current_picture_ptr->motion_val[dir][mv_pos][0] / 2; + chroma_my = s->current_picture_ptr->motion_val[dir][mv_pos][1] / 2; umx = (chroma_mx + (3 << 24)) / 3 - (1 << 24); umy = (chroma_my + (3 << 24)) / 3 - (1 << 24); uvmx = chroma_coeffs[(chroma_mx + (3 << 24)) % 3]; uvmy = chroma_coeffs[(chroma_my + (3 << 24)) % 3]; }else{ int cx, cy; - mx = s->current_picture_ptr->f.motion_val[dir][mv_pos][0] >> 2; - my = s->current_picture_ptr->f.motion_val[dir][mv_pos][1] >> 2; - lx = s->current_picture_ptr->f.motion_val[dir][mv_pos][0] & 3; - ly = s->current_picture_ptr->f.motion_val[dir][mv_pos][1] & 3; - cx = s->current_picture_ptr->f.motion_val[dir][mv_pos][0] / 2; - cy = s->current_picture_ptr->f.motion_val[dir][mv_pos][1] / 2; + mx = s->current_picture_ptr->motion_val[dir][mv_pos][0] >> 2; + my = s->current_picture_ptr->motion_val[dir][mv_pos][1] >> 2; + lx = s->current_picture_ptr->motion_val[dir][mv_pos][0] & 3; + ly = s->current_picture_ptr->motion_val[dir][mv_pos][1] & 3; + cx = s->current_picture_ptr->motion_val[dir][mv_pos][0] / 2; + cy = s->current_picture_ptr->motion_val[dir][mv_pos][1] / 2; umx = cx >> 2; umy = cy >> 2; uvmx = (cx & 3) << 1; @@ -704,7 +704,7 @@ static inline void rv34_mc(RV34DecContext *r, const int block_type, if (HAVE_THREADS && (s->avctx->active_thread_type & FF_THREAD_FRAME)) { /* wait for the referenced mb row to be finished */ int mb_row = s->mb_y + ((yoff + my + 5 + 8 * height) >> 4); - AVFrame *f = dir ? &s->next_picture_ptr->f : &s->last_picture_ptr->f; + ThreadFrame *f = dir ? &s->next_picture_ptr->tf : &s->last_picture_ptr->tf; ff_thread_await_progress(f, mb_row, 0); } @@ -853,11 +853,11 @@ static int rv34_decode_mv(RV34DecContext *r, int block_type) switch(block_type){ case RV34_MB_TYPE_INTRA: case RV34_MB_TYPE_INTRA16x16: - ZERO8x2(s->current_picture_ptr->f.motion_val[0][s->mb_x * 2 + s->mb_y * 2 * s->b8_stride], s->b8_stride); + ZERO8x2(s->current_picture_ptr->motion_val[0][s->mb_x * 2 + s->mb_y * 2 * s->b8_stride], s->b8_stride); return 0; case RV34_MB_SKIP: if(s->pict_type == AV_PICTURE_TYPE_P){ - ZERO8x2(s->current_picture_ptr->f.motion_val[0][s->mb_x * 2 + s->mb_y * 2 * s->b8_stride], s->b8_stride); + ZERO8x2(s->current_picture_ptr->motion_val[0][s->mb_x * 2 + s->mb_y * 2 * s->b8_stride], s->b8_stride); rv34_mc_1mv (r, block_type, 0, 0, 0, 2, 2, 0); break; } @@ -865,23 +865,23 @@ static int rv34_decode_mv(RV34DecContext *r, int block_type) //surprisingly, it uses motion scheme from next reference frame /* wait for the current mb row to be finished */ if (HAVE_THREADS && (s->avctx->active_thread_type & FF_THREAD_FRAME)) - ff_thread_await_progress(&s->next_picture_ptr->f, FFMAX(0, s->mb_y-1), 0); + ff_thread_await_progress(&s->next_picture_ptr->tf, FFMAX(0, s->mb_y-1), 0); - next_bt = s->next_picture_ptr->f.mb_type[s->mb_x + s->mb_y * s->mb_stride]; + next_bt = s->next_picture_ptr->mb_type[s->mb_x + s->mb_y * s->mb_stride]; if(IS_INTRA(next_bt) || IS_SKIP(next_bt)){ - ZERO8x2(s->current_picture_ptr->f.motion_val[0][s->mb_x * 2 + s->mb_y * 2 * s->b8_stride], s->b8_stride); - ZERO8x2(s->current_picture_ptr->f.motion_val[1][s->mb_x * 2 + s->mb_y * 2 * s->b8_stride], s->b8_stride); + ZERO8x2(s->current_picture_ptr->motion_val[0][s->mb_x * 2 + s->mb_y * 2 * s->b8_stride], s->b8_stride); + ZERO8x2(s->current_picture_ptr->motion_val[1][s->mb_x * 2 + s->mb_y * 2 * s->b8_stride], s->b8_stride); }else for(j = 0; j < 2; j++) for(i = 0; i < 2; i++) for(k = 0; k < 2; k++) for(l = 0; l < 2; l++) - s->current_picture_ptr->f.motion_val[l][mv_pos + i + j*s->b8_stride][k] = calc_add_mv(r, l, s->next_picture_ptr->f.motion_val[0][mv_pos + i + j*s->b8_stride][k]); + s->current_picture_ptr->motion_val[l][mv_pos + i + j*s->b8_stride][k] = calc_add_mv(r, l, s->next_picture_ptr->motion_val[0][mv_pos + i + j*s->b8_stride][k]); if(!(IS_16X8(next_bt) || IS_8X16(next_bt) || IS_8X8(next_bt))) //we can use whole macroblock MC rv34_mc_2mv(r, block_type); else rv34_mc_2mv_skip(r); - ZERO8x2(s->current_picture_ptr->f.motion_val[0][s->mb_x * 2 + s->mb_y * 2 * s->b8_stride], s->b8_stride); + ZERO8x2(s->current_picture_ptr->motion_val[0][s->mb_x * 2 + s->mb_y * 2 * s->b8_stride], s->b8_stride); break; case RV34_MB_P_16x16: case RV34_MB_P_MIX16x16: @@ -1149,7 +1149,7 @@ static int rv34_set_deblock_coef(RV34DecContext *r) MpegEncContext *s = &r->s; int hmvmask = 0, vmvmask = 0, i, j; int midx = s->mb_x * 2 + s->mb_y * 2 * s->b8_stride; - int16_t (*motion_val)[2] = &s->current_picture_ptr->f.motion_val[0][midx]; + int16_t (*motion_val)[2] = &s->current_picture_ptr->motion_val[0][midx]; for(j = 0; j < 16; j += 8){ for(i = 0; i < 2; i++){ if(is_mv_diff_gt_3(motion_val + i, 1)) @@ -1192,26 +1192,26 @@ static int rv34_decode_inter_macroblock(RV34DecContext *r, int8_t *intra_types) dist = (s->mb_x - s->resync_mb_x) + (s->mb_y - s->resync_mb_y) * s->mb_width; if(s->mb_x && dist) r->avail_cache[5] = - r->avail_cache[9] = s->current_picture_ptr->f.mb_type[mb_pos - 1]; + r->avail_cache[9] = s->current_picture_ptr->mb_type[mb_pos - 1]; if(dist >= s->mb_width) r->avail_cache[2] = - r->avail_cache[3] = s->current_picture_ptr->f.mb_type[mb_pos - s->mb_stride]; + r->avail_cache[3] = s->current_picture_ptr->mb_type[mb_pos - s->mb_stride]; if(((s->mb_x+1) < s->mb_width) && dist >= s->mb_width - 1) - r->avail_cache[4] = s->current_picture_ptr->f.mb_type[mb_pos - s->mb_stride + 1]; + r->avail_cache[4] = s->current_picture_ptr->mb_type[mb_pos - s->mb_stride + 1]; if(s->mb_x && dist > s->mb_width) - r->avail_cache[1] = s->current_picture_ptr->f.mb_type[mb_pos - s->mb_stride - 1]; + r->avail_cache[1] = s->current_picture_ptr->mb_type[mb_pos - s->mb_stride - 1]; s->qscale = r->si.quant; cbp = cbp2 = rv34_decode_inter_mb_header(r, intra_types); r->cbp_luma [mb_pos] = cbp; r->cbp_chroma[mb_pos] = cbp >> 16; r->deblock_coefs[mb_pos] = rv34_set_deblock_coef(r) | r->cbp_luma[mb_pos]; - s->current_picture_ptr->f.qscale_table[mb_pos] = s->qscale; + s->current_picture_ptr->qscale_table[mb_pos] = s->qscale; if(cbp == -1) return -1; - if (IS_INTRA(s->current_picture_ptr->f.mb_type[mb_pos])){ + if (IS_INTRA(s->current_picture_ptr->mb_type[mb_pos])){ if(r->is16) rv34_output_i16x16(r, intra_types, cbp); else rv34_output_intra(r, intra_types, cbp); return 0; @@ -1294,21 +1294,21 @@ static int rv34_decode_intra_macroblock(RV34DecContext *r, int8_t *intra_types) dist = (s->mb_x - s->resync_mb_x) + (s->mb_y - s->resync_mb_y) * s->mb_width; if(s->mb_x && dist) r->avail_cache[5] = - r->avail_cache[9] = s->current_picture_ptr->f.mb_type[mb_pos - 1]; + r->avail_cache[9] = s->current_picture_ptr->mb_type[mb_pos - 1]; if(dist >= s->mb_width) r->avail_cache[2] = - r->avail_cache[3] = s->current_picture_ptr->f.mb_type[mb_pos - s->mb_stride]; + r->avail_cache[3] = s->current_picture_ptr->mb_type[mb_pos - s->mb_stride]; if(((s->mb_x+1) < s->mb_width) && dist >= s->mb_width - 1) - r->avail_cache[4] = s->current_picture_ptr->f.mb_type[mb_pos - s->mb_stride + 1]; + r->avail_cache[4] = s->current_picture_ptr->mb_type[mb_pos - s->mb_stride + 1]; if(s->mb_x && dist > s->mb_width) - r->avail_cache[1] = s->current_picture_ptr->f.mb_type[mb_pos - s->mb_stride - 1]; + r->avail_cache[1] = s->current_picture_ptr->mb_type[mb_pos - s->mb_stride - 1]; s->qscale = r->si.quant; cbp = rv34_decode_intra_mb_header(r, intra_types); r->cbp_luma [mb_pos] = cbp; r->cbp_chroma[mb_pos] = cbp >> 16; r->deblock_coefs[mb_pos] = 0xFFFF; - s->current_picture_ptr->f.qscale_table[mb_pos] = s->qscale; + s->current_picture_ptr->qscale_table[mb_pos] = s->qscale; if(cbp == -1) return -1; @@ -1444,7 +1444,7 @@ static int rv34_decode_slice(RV34DecContext *r, int end, const uint8_t* buf, int r->loop_filter(r, s->mb_y - 2); if (HAVE_THREADS && (s->avctx->active_thread_type & FF_THREAD_FRAME)) - ff_thread_report_progress(&s->current_picture_ptr->f, + ff_thread_report_progress(&s->current_picture_ptr->tf, s->mb_y - 2, 0); } @@ -1503,6 +1503,8 @@ av_cold int ff_rv34_decode_init(AVCodecContext *avctx) if(!intra_vlcs[0].cbppattern[0].bits) rv34_init_tables(); + avctx->internal->allocate_progress = 1; + return 0; } @@ -1520,6 +1522,7 @@ int ff_rv34_decode_init_thread_copy(AVCodecContext *avctx) if ((err = rv34_decoder_alloc(r)) < 0) return err; } + return 0; } @@ -1563,24 +1566,26 @@ static int finish_frame(AVCodecContext *avctx, AVFrame *pict) { RV34DecContext *r = avctx->priv_data; MpegEncContext *s = &r->s; - int got_picture = 0; + int got_picture = 0, ret; ff_er_frame_end(&s->er); ff_MPV_frame_end(s); s->mb_num_left = 0; if (HAVE_THREADS && (s->avctx->active_thread_type & FF_THREAD_FRAME)) - ff_thread_report_progress(&s->current_picture_ptr->f, INT_MAX, 0); + ff_thread_report_progress(&s->current_picture_ptr->tf, INT_MAX, 0); if (s->pict_type == AV_PICTURE_TYPE_B || s->low_delay) { - *pict = s->current_picture_ptr->f; + if ((ret = av_frame_ref(pict, &s->current_picture_ptr->f)) < 0) + return ret; + ff_print_debug_info(s, s->current_picture_ptr); got_picture = 1; } else if (s->last_picture_ptr != NULL) { - *pict = s->last_picture_ptr->f; + if ((ret = av_frame_ref(pict, &s->last_picture_ptr->f)) < 0) + return ret; + ff_print_debug_info(s, s->last_picture_ptr); got_picture = 1; } - if (got_picture) - ff_print_debug_info(s, pict); return got_picture; } @@ -1595,7 +1600,7 @@ int ff_rv34_decode_frame(AVCodecContext *avctx, MpegEncContext *s = &r->s; AVFrame *pict = data; SliceInfo si; - int i; + int i, ret; int slice_count; const uint8_t *slices_hdr = NULL; int last = 0; @@ -1604,7 +1609,8 @@ int ff_rv34_decode_frame(AVCodecContext *avctx, if (buf_size == 0) { /* special case for last picture */ if (s->low_delay==0 && s->next_picture_ptr) { - *pict = s->next_picture_ptr->f; + if ((ret = av_frame_ref(pict, &s->next_picture_ptr->f)) < 0) + return ret; s->next_picture_ptr = NULL; *got_picture_ptr = 1; @@ -1761,7 +1767,10 @@ int ff_rv34_decode_frame(AVCodecContext *avctx, if(r->loop_filter) r->loop_filter(r, s->mb_height - 1); - *got_picture_ptr = finish_frame(avctx, pict); + ret = finish_frame(avctx, pict); + if (ret < 0) + return ret; + *got_picture_ptr = ret; } else if (HAVE_THREADS && (s->avctx->active_thread_type & FF_THREAD_FRAME)) { av_log(avctx, AV_LOG_INFO, "marking unfished frame as finished\n"); @@ -1770,7 +1779,7 @@ int ff_rv34_decode_frame(AVCodecContext *avctx, ff_er_frame_end(&s->er); ff_MPV_frame_end(s); s->mb_num_left = 0; - ff_thread_report_progress(&s->current_picture_ptr->f, INT_MAX, 0); + ff_thread_report_progress(&s->current_picture_ptr->tf, INT_MAX, 0); return AVERROR_INVALIDDATA; } } diff --git a/libavcodec/rv40.c b/libavcodec/rv40.c index 1f2deac3c9..6f8643dfbf 100644 --- a/libavcodec/rv40.c +++ b/libavcodec/rv40.c @@ -363,7 +363,7 @@ static void rv40_loop_filter(RV34DecContext *r, int row) mb_pos = row * s->mb_stride; for(mb_x = 0; mb_x < s->mb_width; mb_x++, mb_pos++){ - int mbtype = s->current_picture_ptr->f.mb_type[mb_pos]; + int mbtype = s->current_picture_ptr->mb_type[mb_pos]; if(IS_INTRA(mbtype) || IS_SEPARATE_DC(mbtype)) r->cbp_luma [mb_pos] = r->deblock_coefs[mb_pos] = 0xFFFF; if(IS_INTRA(mbtype)) @@ -378,7 +378,7 @@ static void rv40_loop_filter(RV34DecContext *r, int row) unsigned y_to_deblock; int c_to_deblock[2]; - q = s->current_picture_ptr->f.qscale_table[mb_pos]; + q = s->current_picture_ptr->qscale_table[mb_pos]; alpha = rv40_alpha_tab[q]; beta = rv40_beta_tab [q]; betaY = betaC = beta * 3; @@ -393,7 +393,7 @@ static void rv40_loop_filter(RV34DecContext *r, int row) if(avail[i]){ int pos = mb_pos + neighbour_offs_x[i] + neighbour_offs_y[i]*s->mb_stride; mvmasks[i] = r->deblock_coefs[pos]; - mbtype [i] = s->current_picture_ptr->f.mb_type[pos]; + mbtype [i] = s->current_picture_ptr->mb_type[pos]; cbp [i] = r->cbp_luma[pos]; uvcbp[i][0] = r->cbp_chroma[pos] & 0xF; uvcbp[i][1] = r->cbp_chroma[pos] >> 4; diff --git a/libavcodec/s302m.c b/libavcodec/s302m.c index 061f0158bb..66d25f11b4 100644 --- a/libavcodec/s302m.c +++ b/libavcodec/s302m.c @@ -93,7 +93,7 @@ static int s302m_decode_frame(AVCodecContext *avctx, void *data, /* get output buffer */ block_size = (avctx->bits_per_coded_sample + 4) / 4; frame->nb_samples = 2 * (buf_size / block_size) / avctx->channels; - if ((ret = ff_get_buffer(avctx, frame)) < 0) { + if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } diff --git a/libavcodec/sgidec.c b/libavcodec/sgidec.c index 0e72751564..a4b31288f2 100644 --- a/libavcodec/sgidec.c +++ b/libavcodec/sgidec.c @@ -26,7 +26,6 @@ #include "sgi.h" typedef struct SgiState { - AVFrame picture; unsigned int width; unsigned int height; unsigned int depth; @@ -155,8 +154,7 @@ static int decode_frame(AVCodecContext *avctx, AVPacket *avpkt) { SgiState *s = avctx->priv_data; - AVFrame *picture = data; - AVFrame *p = &s->picture; + AVFrame *p = data; unsigned int dimension, rle; int ret = 0; uint8_t *out_buf, *out_end; @@ -206,11 +204,7 @@ static int decode_frame(AVCodecContext *avctx, return -1; avcodec_set_dimensions(avctx, s->width, s->height); - if (p->data[0]) - avctx->release_buffer(avctx, p); - - p->reference = 0; - if (ff_get_buffer(avctx, p) < 0) { + if (ff_get_buffer(avctx, p, 0) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed.\n"); return -1; } @@ -232,7 +226,6 @@ static int decode_frame(AVCodecContext *avctx, } if (ret == 0) { - *picture = s->picture; *got_frame = 1; return avpkt->size; } else { @@ -240,32 +233,11 @@ static int decode_frame(AVCodecContext *avctx, } } -static av_cold int sgi_init(AVCodecContext *avctx){ - SgiState *s = avctx->priv_data; - - avcodec_get_frame_defaults(&s->picture); - avctx->coded_frame = &s->picture; - - return 0; -} - -static av_cold int sgi_end(AVCodecContext *avctx) -{ - SgiState * const s = avctx->priv_data; - - if (s->picture.data[0]) - avctx->release_buffer(avctx, &s->picture); - - return 0; -} - AVCodec ff_sgi_decoder = { .name = "sgi", .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_SGI, .priv_data_size = sizeof(SgiState), - .init = sgi_init, - .close = sgi_end, .decode = decode_frame, .long_name = NULL_IF_CONFIG_SMALL("SGI image"), .capabilities = CODEC_CAP_DR1, diff --git a/libavcodec/shorten.c b/libavcodec/shorten.c index d6c9386c8a..1527946172 100644 --- a/libavcodec/shorten.c +++ b/libavcodec/shorten.c @@ -593,7 +593,7 @@ static int shorten_decode_frame(AVCodecContext *avctx, void *data, if (s->cur_chan == s->channels) { /* get output buffer */ frame->nb_samples = s->blocksize; - if ((ret = ff_get_buffer(avctx, frame)) < 0) { + if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } diff --git a/libavcodec/sipr.c b/libavcodec/sipr.c index a36cdeff95..2d35841336 100644 --- a/libavcodec/sipr.c +++ b/libavcodec/sipr.c @@ -543,7 +543,7 @@ static int sipr_decode_frame(AVCodecContext *avctx, void *data, /* get output buffer */ frame->nb_samples = mode_par->frames_per_packet * subframe_size * mode_par->subframe_count; - if ((ret = ff_get_buffer(avctx, frame)) < 0) { + if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } diff --git a/libavcodec/smacker.c b/libavcodec/smacker.c index bc75a17e63..c37fb14a4d 100644 --- a/libavcodec/smacker.c +++ b/libavcodec/smacker.c @@ -358,18 +358,16 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, GetByteContext gb2; GetBitContext gb; int blocks, blk, bw, bh; - int i; + int i, ret; int stride; int flags; if (avpkt->size <= 769) return 0; - smk->pic.reference = 1; - smk->pic.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE; - if(avctx->reget_buffer(avctx, &smk->pic) < 0){ + if ((ret = ff_reget_buffer(avctx, &smk->pic)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); - return -1; + return ret; } /* make the palette available on the way out */ @@ -497,8 +495,10 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, } + if ((ret = av_frame_ref(data, &smk->pic)) < 0) + return ret; + *got_frame = 1; - *(AVFrame*)data = smk->pic; /* always report that the buffer was completely consumed */ return avpkt->size; @@ -548,8 +548,7 @@ static av_cold int decode_end(AVCodecContext *avctx) av_freep(&smk->full_tbl); av_freep(&smk->type_tbl); - if (smk->pic.data[0]) - avctx->release_buffer(avctx, &smk->pic); + av_frame_unref(&smk->pic); return 0; } @@ -614,7 +613,7 @@ static int smka_decode_frame(AVCodecContext *avctx, void *data, /* get output buffer */ frame->nb_samples = unp_size / (avctx->channels * (bits + 1)); - if ((ret = ff_get_buffer(avctx, frame)) < 0) { + if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } diff --git a/libavcodec/smc.c b/libavcodec/smc.c index 1834003a39..de81a43e91 100644 --- a/libavcodec/smc.c +++ b/libavcodec/smc.c @@ -35,6 +35,7 @@ #include "libavutil/intreadwrite.h" #include "avcodec.h" #include "bytestream.h" +#include "internal.h" #define CPAIR 2 #define CQUAD 4 @@ -429,15 +430,13 @@ static int smc_decode_frame(AVCodecContext *avctx, int buf_size = avpkt->size; SmcContext *s = avctx->priv_data; const uint8_t *pal = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE, NULL); + int ret; bytestream2_init(&s->gb, buf, buf_size); - s->frame.reference = 1; - s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | - FF_BUFFER_HINTS_REUSABLE | FF_BUFFER_HINTS_READABLE; - if (avctx->reget_buffer(avctx, &s->frame)) { + if ((ret = ff_reget_buffer(avctx, &s->frame)) < 0) { av_log(s->avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); - return -1; + return ret; } if (pal) { @@ -448,7 +447,8 @@ static int smc_decode_frame(AVCodecContext *avctx, smc_decode_stream(s); *got_frame = 1; - *(AVFrame*)data = s->frame; + if ((ret = av_frame_ref(data, &s->frame)) < 0) + return ret; /* always report that the buffer was completely consumed */ return buf_size; @@ -458,8 +458,7 @@ static av_cold int smc_decode_end(AVCodecContext *avctx) { SmcContext *s = avctx->priv_data; - if (s->frame.data[0]) - avctx->release_buffer(avctx, &s->frame); + av_frame_unref(&s->frame); return 0; } diff --git a/libavcodec/sunrast.c b/libavcodec/sunrast.c index a44cdf026a..56e915d047 100644 --- a/libavcodec/sunrast.c +++ b/libavcodec/sunrast.c @@ -26,27 +26,12 @@ #include "internal.h" #include "sunrast.h" -typedef struct SUNRASTContext { - AVFrame picture; -} SUNRASTContext; - -static av_cold int sunrast_init(AVCodecContext *avctx) { - SUNRASTContext *s = avctx->priv_data; - - avcodec_get_frame_defaults(&s->picture); - avctx->coded_frame = &s->picture; - - return 0; -} - static int sunrast_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { const uint8_t *buf = avpkt->data; const uint8_t *buf_end = avpkt->data + avpkt->size; - SUNRASTContext * const s = avctx->priv_data; - AVFrame *picture = data; - AVFrame * const p = &s->picture; + AVFrame * const p = data; unsigned int w, h, depth, type, maptype, maplength, stride, x, y, len, alen; uint8_t *ptr; const uint8_t *bufstart = buf; @@ -105,12 +90,9 @@ static int sunrast_decode_frame(AVCodecContext *avctx, void *data, return AVERROR_INVALIDDATA; } - if (p->data[0]) - avctx->release_buffer(avctx, p); - if (w != avctx->width || h != avctx->height) avcodec_set_dimensions(avctx, w, h); - if ((ret = ff_get_buffer(avctx, p)) < 0) { + if ((ret = ff_get_buffer(avctx, p, 0)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } @@ -181,28 +163,15 @@ static int sunrast_decode_frame(AVCodecContext *avctx, void *data, } } - *picture = s->picture; *got_frame = 1; return buf - bufstart; } -static av_cold int sunrast_end(AVCodecContext *avctx) { - SUNRASTContext *s = avctx->priv_data; - - if(s->picture.data[0]) - avctx->release_buffer(avctx, &s->picture); - - return 0; -} - AVCodec ff_sunrast_decoder = { .name = "sunrast", .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_SUNRAST, - .priv_data_size = sizeof(SUNRASTContext), - .init = sunrast_init, - .close = sunrast_end, .decode = sunrast_decode_frame, .capabilities = CODEC_CAP_DR1, .long_name = NULL_IF_CONFIG_SMALL("Sun Rasterfile image"), diff --git a/libavcodec/svq1dec.c b/libavcodec/svq1dec.c index dc041dd0d7..c5d56ee75f 100644 --- a/libavcodec/svq1dec.c +++ b/libavcodec/svq1dec.c @@ -60,7 +60,7 @@ typedef struct svq1_pmv_s { typedef struct SVQ1Context { DSPContext dsp; GetBitContext gb; - AVFrame *cur, *prev; + AVFrame *prev; int width; int height; int frame_code; @@ -612,14 +612,11 @@ static int svq1_decode_frame(AVCodecContext *avctx, void *data, const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; SVQ1Context *s = avctx->priv_data; - AVFrame *cur = s->cur; + AVFrame *cur = data; uint8_t *current; int result, i, x, y, width, height; svq1_pmv *pmv; - if (cur->data[0]) - avctx->release_buffer(avctx, cur); - /* initialize bit buffer */ init_get_bits(&s->gb, buf, buf_size * 8); @@ -651,7 +648,7 @@ static int svq1_decode_frame(AVCodecContext *avctx, void *data, avctx->skip_frame >= AVDISCARD_ALL) return buf_size; - result = ff_get_buffer(avctx, cur); + result = ff_get_buffer(avctx, cur, s->nonref ? 0 : AV_GET_BUFFER_FLAG_REF); if (result < 0) return result; @@ -722,9 +719,12 @@ static int svq1_decode_frame(AVCodecContext *avctx, void *data, } } - *(AVFrame*)data = *cur; - if (!s->nonref) - FFSWAP(AVFrame*, s->cur, s->prev); + if (!s->nonref) { + av_frame_unref(s->prev); + result = av_frame_ref(s->prev, cur); + if (result < 0) + goto err; + } *got_frame = 1; result = buf_size; @@ -740,13 +740,9 @@ static av_cold int svq1_decode_init(AVCodecContext *avctx) int i; int offset = 0; - s->cur = avcodec_alloc_frame(); s->prev = avcodec_alloc_frame(); - if (!s->cur || !s->prev) { - avcodec_free_frame(&s->cur); - avcodec_free_frame(&s->prev); + if (!s->prev) return AVERROR(ENOMEM); - } s->width = avctx->width + 3 & ~3; s->height = avctx->height + 3 & ~3; @@ -797,11 +793,6 @@ static av_cold int svq1_decode_end(AVCodecContext *avctx) { SVQ1Context *s = avctx->priv_data; - if (s->cur->data[0]) - avctx->release_buffer(avctx, s->cur); - if (s->prev->data[0]) - avctx->release_buffer(avctx, s->prev); - avcodec_free_frame(&s->cur); avcodec_free_frame(&s->prev); return 0; @@ -811,10 +802,7 @@ static void svq1_flush(AVCodecContext *avctx) { SVQ1Context *s = avctx->priv_data; - if (s->cur->data[0]) - avctx->release_buffer(avctx, s->cur); - if (s->prev->data[0]) - avctx->release_buffer(avctx, s->prev); + av_frame_unref(s->prev); } AVCodec ff_svq1_decoder = { diff --git a/libavcodec/svq1enc.c b/libavcodec/svq1enc.c index e654b4ecb3..22668958a9 100644 --- a/libavcodec/svq1enc.c +++ b/libavcodec/svq1enc.c @@ -324,9 +324,9 @@ static int svq1_encode_plane(SVQ1Context *s, int plane, s->m.current_picture.mb_mean = (uint8_t *)s->dummy; s->m.current_picture.mb_var = (uint16_t *)s->dummy; s->m.current_picture.mc_mb_var = (uint16_t *)s->dummy; - s->m.current_picture.f.mb_type = s->dummy; + s->m.current_picture.mb_type = s->dummy; - s->m.current_picture.f.motion_val[0] = s->motion_val8[plane] + 2; + s->m.current_picture.motion_val[0] = s->motion_val8[plane] + 2; s->m.p_mv_table = s->motion_val16[plane] + s->m.mb_stride + 1; s->m.dsp = s->dsp; // move @@ -550,8 +550,8 @@ static int svq1_encode_frame(AVCodecContext *avctx, AVPacket *pkt, } if (!s->current_picture.data[0]) { - ff_get_buffer(avctx, &s->current_picture); - ff_get_buffer(avctx, &s->last_picture); + ff_get_buffer(avctx, &s->current_picture, 0); + ff_get_buffer(avctx, &s->last_picture, 0); s->scratchbuf = av_malloc(s->current_picture.linesize[0] * 16 * 2); } @@ -613,6 +613,9 @@ static av_cold int svq1_encode_end(AVCodecContext *avctx) av_freep(&s->motion_val16[i]); } + av_frame_unref(&s->current_picture); + av_frame_unref(&s->last_picture); + return 0; } diff --git a/libavcodec/svq3.c b/libavcodec/svq3.c index 04c18587ce..f9d8d46d01 100644 --- a/libavcodec/svq3.c +++ b/libavcodec/svq3.c @@ -370,8 +370,8 @@ static inline int svq3_mc_dir(SVQ3Context *s, int size, int mode, if (mode != PREDICT_MODE) { pred_motion(h, k, part_width >> 2, dir, 1, &mx, &my); } else { - mx = s->next_pic->f.motion_val[0][b_xy][0] << 1; - my = s->next_pic->f.motion_val[0][b_xy][1] << 1; + mx = s->next_pic->motion_val[0][b_xy][0] << 1; + my = s->next_pic->motion_val[0][b_xy][1] << 1; if (dir == 0) { mx = mx * h->frame_num_offset / @@ -452,7 +452,7 @@ static inline int svq3_mc_dir(SVQ3Context *s, int size, int mode, } /* write back motion vectors */ - fill_rectangle(h->cur_pic.f.motion_val[dir][b_xy], + fill_rectangle(h->cur_pic.motion_val[dir][b_xy], part_width >> 2, part_height >> 2, h->b_stride, pack16to32(mx, my), 4); } @@ -476,7 +476,7 @@ static int svq3_decode_mb(SVQ3Context *s, unsigned int mb_type) if (mb_type == 0) { /* SKIP */ if (h->pict_type == AV_PICTURE_TYPE_P || - s->next_pic->f.mb_type[mb_xy] == -1) { + s->next_pic->mb_type[mb_xy] == -1) { svq3_mc_dir_part(s, 16 * h->mb_x, 16 * h->mb_y, 16, 16, 0, 0, 0, 0, 0, 0); @@ -486,7 +486,7 @@ static int svq3_decode_mb(SVQ3Context *s, unsigned int mb_type) mb_type = MB_TYPE_SKIP; } else { - mb_type = FFMIN(s->next_pic->f.mb_type[mb_xy], 6); + mb_type = FFMIN(s->next_pic->mb_type[mb_xy], 6); if (svq3_mc_dir(s, mb_type, PREDICT_MODE, 0, 0) < 0) return -1; if (svq3_mc_dir(s, mb_type, PREDICT_MODE, 1, 1) < 0) @@ -516,21 +516,21 @@ static int svq3_decode_mb(SVQ3Context *s, unsigned int mb_type) if (h->mb_x > 0 && h->intra4x4_pred_mode[h->mb2br_xy[mb_xy - 1] + 6] != -1) { for (i = 0; i < 4; i++) AV_COPY32(h->mv_cache[m][scan8[0] - 1 + i * 8], - h->cur_pic.f.motion_val[m][b_xy - 1 + i * h->b_stride]); + h->cur_pic.motion_val[m][b_xy - 1 + i * h->b_stride]); } else { for (i = 0; i < 4; i++) AV_ZERO32(h->mv_cache[m][scan8[0] - 1 + i * 8]); } if (h->mb_y > 0) { memcpy(h->mv_cache[m][scan8[0] - 1 * 8], - h->cur_pic.f.motion_val[m][b_xy - h->b_stride], + h->cur_pic.motion_val[m][b_xy - h->b_stride], 4 * 2 * sizeof(int16_t)); memset(&h->ref_cache[m][scan8[0] - 1 * 8], (h->intra4x4_pred_mode[h->mb2br_xy[mb_xy - h->mb_stride]] == -1) ? PART_NOT_AVAILABLE : 1, 4); if (h->mb_x < h->mb_width - 1) { AV_COPY32(h->mv_cache[m][scan8[0] + 4 - 1 * 8], - h->cur_pic.f.motion_val[m][b_xy - h->b_stride + 4]); + h->cur_pic.motion_val[m][b_xy - h->b_stride + 4]); h->ref_cache[m][scan8[0] + 4 - 1 * 8] = (h->intra4x4_pred_mode[h->mb2br_xy[mb_xy - h->mb_stride + 1] + 6] == -1 || h->intra4x4_pred_mode[h->mb2br_xy[mb_xy - h->mb_stride]] == -1) ? PART_NOT_AVAILABLE : 1; @@ -538,7 +538,7 @@ static int svq3_decode_mb(SVQ3Context *s, unsigned int mb_type) h->ref_cache[m][scan8[0] + 4 - 1 * 8] = PART_NOT_AVAILABLE; if (h->mb_x > 0) { AV_COPY32(h->mv_cache[m][scan8[0] - 1 - 1 * 8], - h->cur_pic.f.motion_val[m][b_xy - h->b_stride - 1]); + h->cur_pic.motion_val[m][b_xy - h->b_stride - 1]); h->ref_cache[m][scan8[0] - 1 - 1 * 8] = (h->intra4x4_pred_mode[h->mb2br_xy[mb_xy - h->mb_stride - 1] + 3] == -1) ? PART_NOT_AVAILABLE : 1; } else @@ -561,7 +561,7 @@ static int svq3_decode_mb(SVQ3Context *s, unsigned int mb_type) return -1; } else { for (i = 0; i < 4; i++) - memset(h->cur_pic.f.motion_val[0][b_xy + i * h->b_stride], + memset(h->cur_pic.motion_val[0][b_xy + i * h->b_stride], 0, 4 * 2 * sizeof(int16_t)); } if (mb_type != 1) { @@ -569,7 +569,7 @@ static int svq3_decode_mb(SVQ3Context *s, unsigned int mb_type) return -1; } else { for (i = 0; i < 4; i++) - memset(h->cur_pic.f.motion_val[1][b_xy + i * h->b_stride], + memset(h->cur_pic.motion_val[1][b_xy + i * h->b_stride], 0, 4 * 2 * sizeof(int16_t)); } } @@ -651,11 +651,11 @@ static int svq3_decode_mb(SVQ3Context *s, unsigned int mb_type) if (!IS_INTER(mb_type) && h->pict_type != AV_PICTURE_TYPE_I) { for (i = 0; i < 4; i++) - memset(h->cur_pic.f.motion_val[0][b_xy + i * h->b_stride], + memset(h->cur_pic.motion_val[0][b_xy + i * h->b_stride], 0, 4 * 2 * sizeof(int16_t)); if (h->pict_type == AV_PICTURE_TYPE_B) { for (i = 0; i < 4; i++) - memset(h->cur_pic.f.motion_val[1][b_xy + i * h->b_stride], + memset(h->cur_pic.motion_val[1][b_xy + i * h->b_stride], 0, 4 * 2 * sizeof(int16_t)); } } @@ -743,7 +743,7 @@ static int svq3_decode_mb(SVQ3Context *s, unsigned int mb_type) } h->cbp = cbp; - h->cur_pic.f.mb_type[mb_xy] = mb_type; + h->cur_pic.mb_type[mb_xy] = mb_type; if (IS_INTRA(mb_type)) h->chroma_pred_mode = ff_h264_check_intra_pred_mode(h, DC_PRED8x8, 1); @@ -1016,6 +1016,18 @@ static av_cold int svq3_decode_init(AVCodecContext *avctx) return 0; } +static void free_picture(AVCodecContext *avctx, Picture *pic) +{ + int i; + for (i = 0; i < 2; i++) { + av_buffer_unref(&pic->motion_val_buf[i]); + av_buffer_unref(&pic->ref_index_buf[i]); + } + av_buffer_unref(&pic->mb_type_buf); + + av_frame_unref(&pic->f); +} + static int get_buffer(AVCodecContext *avctx, Picture *pic) { SVQ3Context *s = avctx->priv_data; @@ -1026,27 +1038,34 @@ static int get_buffer(AVCodecContext *avctx, Picture *pic) const int b4_array_size = b4_stride * h->mb_height * 4; int ret; - if (!pic->motion_val_base[0]) { + if (!pic->motion_val_buf[0]) { int i; - pic->mb_type_base = av_mallocz((big_mb_num + h->mb_stride) * sizeof(uint32_t)); - if (!pic->mb_type_base) + pic->mb_type_buf = av_buffer_allocz((big_mb_num + h->mb_stride) * sizeof(uint32_t)); + if (!pic->mb_type_buf) return AVERROR(ENOMEM); - pic->f.mb_type = pic->mb_type_base + 2 * h->mb_stride + 1; + pic->mb_type = (uint32_t*)pic->mb_type_buf->data + 2 * h->mb_stride + 1; for (i = 0; i < 2; i++) { - pic->motion_val_base[i] = av_mallocz(2 * (b4_array_size + 4) * sizeof(int16_t)); - pic->f.ref_index[i] = av_mallocz(4 * mb_array_size); - if (!pic->motion_val_base[i] || !pic->f.ref_index[i]) - return AVERROR(ENOMEM); + pic->motion_val_buf[i] = av_buffer_allocz(2 * (b4_array_size + 4) * sizeof(int16_t)); + pic->ref_index_buf[i] = av_buffer_allocz(4 * mb_array_size); + if (!pic->motion_val_buf[i] || !pic->ref_index_buf[i]) { + ret = AVERROR(ENOMEM); + goto fail; + } - pic->f.motion_val[i] = pic->motion_val_base[i] + 4; + pic->motion_val[i] = (int16_t (*)[2])pic->motion_val_buf[i]->data + 4; + pic->ref_index[i] = pic->ref_index_buf[i]->data; } } pic->f.motion_subsample_log2 = 2; - pic->f.reference = !(h->pict_type == AV_PICTURE_TYPE_B); + pic->reference = !(h->pict_type == AV_PICTURE_TYPE_B); + + ret = ff_get_buffer(avctx, &pic->f, + pic->reference ? AV_GET_BUFFER_FLAG_REF : 0); + if (ret < 0) + goto fail; - ret = ff_get_buffer(avctx, &pic->f); if (!h->edge_emu_buffer) { h->edge_emu_buffer = av_mallocz(pic->f.linesize[0] * 17); if (!h->edge_emu_buffer) @@ -1056,6 +1075,9 @@ static int get_buffer(AVCodecContext *avctx, Picture *pic) h->linesize = pic->f.linesize[0]; h->uvlinesize = pic->f.linesize[1]; + return 0; +fail: + free_picture(avctx, pic); return ret; } @@ -1071,7 +1093,9 @@ static int svq3_decode_frame(AVCodecContext *avctx, void *data, /* special case for last picture */ if (buf_size == 0) { if (s->next_pic->f.data[0] && !h->low_delay && !s->last_frame_output) { - *(AVFrame *) data = s->next_pic->f; + ret = av_frame_ref(data, &s->next_pic->f); + if (ret < 0) + return ret; s->last_frame_output = 1; *got_frame = 1; } @@ -1090,8 +1114,7 @@ static int svq3_decode_frame(AVCodecContext *avctx, void *data, if (h->pict_type != AV_PICTURE_TYPE_B) FFSWAP(Picture*, s->next_pic, s->last_pic); - if (s->cur_pic->f.data[0]) - avctx->release_buffer(avctx, &s->cur_pic->f); + av_frame_unref(&s->cur_pic->f); /* for skipping the frame */ s->cur_pic->f.pict_type = h->pict_type; @@ -1102,7 +1125,11 @@ static int svq3_decode_frame(AVCodecContext *avctx, void *data, return ret; h->cur_pic_ptr = s->cur_pic; + av_frame_unref(&h->cur_pic.f); h->cur_pic = *s->cur_pic; + ret = av_frame_ref(&h->cur_pic.f, &s->cur_pic->f); + if (ret < 0) + return ret; for (i = 0; i < 16; i++) { h->block_offset[i] = (4 * ((scan8[i] - scan8[0]) & 7)) + 4 * h->linesize * ((scan8[i] - scan8[0]) >> 3); @@ -1223,7 +1250,7 @@ static int svq3_decode_frame(AVCodecContext *avctx, void *data, ff_h264_hl_decode_mb(h); if (h->pict_type != AV_PICTURE_TYPE_B && !h->low_delay) - h->cur_pic.f.mb_type[h->mb_x + h->mb_y * h->mb_stride] = + h->cur_pic.mb_type[h->mb_x + h->mb_y * h->mb_stride] = (h->pict_type == AV_PICTURE_TYPE_P && mb_type < 8) ? (mb_type - 1) : -1; } @@ -1233,9 +1260,11 @@ static int svq3_decode_frame(AVCodecContext *avctx, void *data, } if (h->pict_type == AV_PICTURE_TYPE_B || h->low_delay) - *(AVFrame *)data = s->cur_pic->f; - else - *(AVFrame *)data = s->last_pic->f; + ret = av_frame_ref(data, &s->cur_pic->f); + else if (s->last_pic->f.data[0]) + ret = av_frame_ref(data, &s->last_pic->f); + if (ret < 0) + return ret; /* Do not output the last pic after seeking. */ if (s->last_pic->f.data[0] || h->low_delay) @@ -1243,25 +1272,13 @@ static int svq3_decode_frame(AVCodecContext *avctx, void *data, if (h->pict_type != AV_PICTURE_TYPE_B) { FFSWAP(Picture*, s->cur_pic, s->next_pic); + } else { + av_frame_unref(&s->cur_pic->f); } return buf_size; } -static void free_picture(AVCodecContext *avctx, Picture *pic) -{ - int i; - for (i = 0; i < 2; i++) { - av_freep(&pic->motion_val_base[i]); - av_freep(&pic->f.ref_index[i]); - } - av_freep(&pic->mb_type_base); - - if (pic->f.data[0]) - avctx->release_buffer(avctx, &pic->f); - av_freep(&pic); -} - static int svq3_decode_end(AVCodecContext *avctx) { SVQ3Context *s = avctx->priv_data; @@ -1270,6 +1287,11 @@ static int svq3_decode_end(AVCodecContext *avctx) free_picture(avctx, s->cur_pic); free_picture(avctx, s->next_pic); free_picture(avctx, s->last_pic); + av_freep(&s->cur_pic); + av_freep(&s->next_pic); + av_freep(&s->last_pic); + + av_frame_unref(&h->cur_pic.f); ff_h264_free_context(h); diff --git a/libavcodec/takdec.c b/libavcodec/takdec.c index 48a424ebb7..a9b8c6664c 100644 --- a/libavcodec/takdec.c +++ b/libavcodec/takdec.c @@ -740,7 +740,7 @@ static int tak_decode_frame(AVCodecContext *avctx, void *data, : s->ti.frame_samples; frame->nb_samples = s->nb_samples; - if ((ret = ff_get_buffer(avctx, frame)) < 0) + if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) return ret; if (avctx->bits_per_coded_sample <= 16) { diff --git a/libavcodec/targa.c b/libavcodec/targa.c index 54eea7df65..993f02c011 100644 --- a/libavcodec/targa.c +++ b/libavcodec/targa.c @@ -27,7 +27,6 @@ #include "targa.h" typedef struct TargaContext { - AVFrame picture; GetByteContext gb; int color_type; @@ -99,8 +98,7 @@ static int decode_frame(AVCodecContext *avctx, AVPacket *avpkt) { TargaContext * const s = avctx->priv_data; - AVFrame *picture = data; - AVFrame * const p = &s->picture; + AVFrame * const p = data; uint8_t *dst; int stride; int idlen, compr, y, w, h, bpp, flags, ret; @@ -144,14 +142,11 @@ static int decode_frame(AVCodecContext *avctx, return AVERROR_INVALIDDATA; } - if(s->picture.data[0]) - avctx->release_buffer(avctx, &s->picture); - if ((ret = av_image_check_size(w, h, 0, avctx)) < 0) return ret; if(w != avctx->width || h != avctx->height) avcodec_set_dimensions(avctx, w, h); - if ((ret = ff_get_buffer(avctx, p)) < 0){ + if ((ret = ff_get_buffer(avctx, p, 0)) < 0){ av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } @@ -232,37 +227,16 @@ static int decode_frame(AVCodecContext *avctx, } } - *picture = s->picture; *got_frame = 1; return avpkt->size; } -static av_cold int targa_init(AVCodecContext *avctx){ - TargaContext *s = avctx->priv_data; - - avcodec_get_frame_defaults(&s->picture); - avctx->coded_frame = &s->picture; - - return 0; -} - -static av_cold int targa_end(AVCodecContext *avctx){ - TargaContext *s = avctx->priv_data; - - if(s->picture.data[0]) - avctx->release_buffer(avctx, &s->picture); - - return 0; -} - AVCodec ff_targa_decoder = { .name = "targa", .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_TARGA, .priv_data_size = sizeof(TargaContext), - .init = targa_init, - .close = targa_end, .decode = decode_frame, .capabilities = CODEC_CAP_DR1, .long_name = NULL_IF_CONFIG_SMALL("Truevision Targa image"), diff --git a/libavcodec/thread.h b/libavcodec/thread.h index 99b0ce146a..864e67eb98 100644 --- a/libavcodec/thread.h +++ b/libavcodec/thread.h @@ -27,9 +27,19 @@ #ifndef AVCODEC_THREAD_H #define AVCODEC_THREAD_H +#include "libavutil/buffer.h" + #include "config.h" #include "avcodec.h" +typedef struct ThreadFrame { + AVFrame *f; + AVCodecContext *owner; + // progress->data is an array of 2 ints holding progress for top/bottom + // fields + AVBufferRef *progress; +} ThreadFrame; + /** * Wait for decoding threads to finish and reset internal state. * Called by avcodec_flush_buffers(). @@ -71,7 +81,7 @@ void ff_thread_finish_setup(AVCodecContext *avctx); * @param field The field being decoded, for field-picture codecs. * 0 for top field or frame pictures, 1 for bottom field. */ -void ff_thread_report_progress(AVFrame *f, int progress, int field); +void ff_thread_report_progress(ThreadFrame *f, int progress, int field); /** * Wait for earlier decoding threads to finish reference pictures. @@ -85,7 +95,7 @@ void ff_thread_report_progress(AVFrame *f, int progress, int field); * @param field The field being referenced, for field-picture codecs. * 0 for top field or frame pictures, 1 for bottom field. */ -void ff_thread_await_progress(AVFrame *f, int progress, int field); +void ff_thread_await_progress(ThreadFrame *f, int progress, int field); /** * Wrapper around get_buffer() for frame-multithreaded codecs. @@ -95,7 +105,7 @@ void ff_thread_await_progress(AVFrame *f, int progress, int field); * @param avctx The current context. * @param f The frame to write into. */ -int ff_thread_get_buffer(AVCodecContext *avctx, AVFrame *f); +int ff_thread_get_buffer(AVCodecContext *avctx, ThreadFrame *f, int flags); /** * Wrapper around release_buffer() frame-for multithreaded codecs. @@ -108,7 +118,9 @@ int ff_thread_get_buffer(AVCodecContext *avctx, AVFrame *f); * @param avctx The current context. * @param f The picture being released. */ -void ff_thread_release_buffer(AVCodecContext *avctx, AVFrame *f); +void ff_thread_release_buffer(AVCodecContext *avctx, ThreadFrame *f); + +int ff_thread_ref_frame(ThreadFrame *dst, ThreadFrame *src); int ff_thread_init(AVCodecContext *s); void ff_thread_free(AVCodecContext *s); diff --git a/libavcodec/tiertexseqv.c b/libavcodec/tiertexseqv.c index a9064eca24..5d5d69434b 100644 --- a/libavcodec/tiertexseqv.c +++ b/libavcodec/tiertexseqv.c @@ -27,6 +27,7 @@ #include "avcodec.h" #define BITSTREAM_READER_LE #include "get_bits.h" +#include "internal.h" typedef struct SeqVideoContext { @@ -227,21 +228,21 @@ static int seqvideo_decode_frame(AVCodecContext *avctx, { const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; + int ret; SeqVideoContext *seq = avctx->priv_data; - seq->frame.reference = 1; - seq->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE; - if (avctx->reget_buffer(avctx, &seq->frame)) { + if ((ret = ff_reget_buffer(avctx, &seq->frame)) < 0) { av_log(seq->avctx, AV_LOG_ERROR, "tiertexseqvideo: reget_buffer() failed\n"); - return -1; + return ret; } if (seqvideo_decode(seq, buf, buf_size)) return AVERROR_INVALIDDATA; + if ((ret = av_frame_ref(data, &seq->frame)) < 0) + return ret; *got_frame = 1; - *(AVFrame *)data = seq->frame; return buf_size; } @@ -250,8 +251,7 @@ static av_cold int seqvideo_decode_end(AVCodecContext *avctx) { SeqVideoContext *seq = avctx->priv_data; - if (seq->frame.data[0]) - avctx->release_buffer(avctx, &seq->frame); + av_frame_unref(&seq->frame); return 0; } diff --git a/libavcodec/tiff.c b/libavcodec/tiff.c index dd25190ecf..79c93cbb8a 100644 --- a/libavcodec/tiff.c +++ b/libavcodec/tiff.c @@ -41,7 +41,6 @@ typedef struct TiffContext { AVCodecContext *avctx; - AVFrame picture; int width, height; unsigned int bpp, bppcount; @@ -245,7 +244,7 @@ static int tiff_unpack_strip(TiffContext *s, uint8_t *dst, int stride, return 0; } -static int init_image(TiffContext *s) +static int init_image(TiffContext *s, AVFrame *frame) { int i, ret; uint32_t *pal; @@ -280,18 +279,16 @@ static int init_image(TiffContext *s) return ret; avcodec_set_dimensions(s->avctx, s->width, s->height); } - if (s->picture.data[0]) - s->avctx->release_buffer(s->avctx, &s->picture); - if ((ret = ff_get_buffer(s->avctx, &s->picture)) < 0) { + if ((ret = ff_get_buffer(s->avctx, frame, 0)) < 0) { av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } if (s->avctx->pix_fmt == AV_PIX_FMT_PAL8) { if (s->palette_is_set) { - memcpy(s->picture.data[1], s->palette, sizeof(s->palette)); + memcpy(frame->data[1], s->palette, sizeof(s->palette)); } else { /* make default grayscale pal */ - pal = (uint32_t *) s->picture.data[1]; + pal = (uint32_t *) frame->data[1]; for (i = 0; i < 256; i++) pal[i] = i * 0x010101; } @@ -545,8 +542,7 @@ static int decode_frame(AVCodecContext *avctx, const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; TiffContext *const s = avctx->priv_data; - AVFrame *picture = data; - AVFrame *const p = &s->picture; + AVFrame *const p = data; const uint8_t *orig_buf = buf, *end_buf = buf + buf_size; unsigned off; int id, le, ret; @@ -599,7 +595,7 @@ static int decode_frame(AVCodecContext *avctx, return AVERROR_INVALIDDATA; } /* now we have the data and may start decoding */ - if ((ret = init_image(s)) < 0) + if ((ret = init_image(s, p)) < 0) return ret; if (s->strips == 1 && !s->stripsize) { @@ -647,14 +643,13 @@ static int decode_frame(AVCodecContext *avctx, uint8_t *src; int j; - src = s->picture.data[0]; + src = p->data[0]; for (j = 0; j < s->height; j++) { - for (i = 0; i < s->picture.linesize[0]; i++) + for (i = 0; i < p->linesize[0]; i++) src[i] = 255 - src[i]; - src += s->picture.linesize[0]; + src += p->linesize[0]; } } - *picture = s->picture; *got_frame = 1; return buf_size; @@ -667,8 +662,6 @@ static av_cold int tiff_init(AVCodecContext *avctx) s->width = 0; s->height = 0; s->avctx = avctx; - avcodec_get_frame_defaults(&s->picture); - avctx->coded_frame = &s->picture; ff_lzw_decode_open(&s->lzw); ff_ccitt_unpack_init(); @@ -680,8 +673,6 @@ static av_cold int tiff_end(AVCodecContext *avctx) TiffContext *const s = avctx->priv_data; ff_lzw_decode_close(&s->lzw); - if (s->picture.data[0]) - avctx->release_buffer(avctx, &s->picture); return 0; } diff --git a/libavcodec/tmv.c b/libavcodec/tmv.c index 29d8e15fd9..c1e4d253ec 100644 --- a/libavcodec/tmv.c +++ b/libavcodec/tmv.c @@ -34,14 +34,10 @@ #include "cga_data.h" -typedef struct TMVContext { - AVFrame pic; -} TMVContext; - static int tmv_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { - TMVContext *tmv = avctx->priv_data; + AVFrame *frame = data; const uint8_t *src = avpkt->data; uint8_t *dst; unsigned char_cols = avctx->width >> 3; @@ -49,10 +45,7 @@ static int tmv_decode_frame(AVCodecContext *avctx, void *data, unsigned x, y, fg, bg, c; int ret; - if (tmv->pic.data[0]) - avctx->release_buffer(avctx, &tmv->pic); - - if ((ret = ff_get_buffer(avctx, &tmv->pic)) < 0) { + if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } @@ -64,26 +57,26 @@ static int tmv_decode_frame(AVCodecContext *avctx, void *data, return AVERROR_INVALIDDATA; } - tmv->pic.pict_type = AV_PICTURE_TYPE_I; - tmv->pic.key_frame = 1; - dst = tmv->pic.data[0]; + frame->pict_type = AV_PICTURE_TYPE_I; + frame->key_frame = 1; + dst = frame->data[0]; - tmv->pic.palette_has_changed = 1; - memcpy(tmv->pic.data[1], ff_cga_palette, 16 * 4); + frame->palette_has_changed = 1; + memcpy(frame->data[1], ff_cga_palette, 16 * 4); for (y = 0; y < char_rows; y++) { for (x = 0; x < char_cols; x++) { c = *src++; bg = *src >> 4; fg = *src++ & 0xF; - ff_draw_pc_font(dst + x * 8, tmv->pic.linesize[0], + ff_draw_pc_font(dst + x * 8, frame->linesize[0], ff_cga_font, 8, c, fg, bg); } - dst += tmv->pic.linesize[0] * 8; + dst += frame->linesize[0] * 8; } *got_frame = 1; - *(AVFrame *)data = tmv->pic; + return avpkt->size; } @@ -93,23 +86,11 @@ static av_cold int tmv_decode_init(AVCodecContext *avctx) return 0; } -static av_cold int tmv_decode_close(AVCodecContext *avctx) -{ - TMVContext *tmv = avctx->priv_data; - - if (tmv->pic.data[0]) - avctx->release_buffer(avctx, &tmv->pic); - - return 0; -} - AVCodec ff_tmv_decoder = { .name = "tmv", .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_TMV, - .priv_data_size = sizeof(TMVContext), .init = tmv_decode_init, - .close = tmv_decode_close, .decode = tmv_decode_frame, .capabilities = CODEC_CAP_DR1, .long_name = NULL_IF_CONFIG_SMALL("8088flex TMV"), diff --git a/libavcodec/truemotion1.c b/libavcodec/truemotion1.c index 73f7056965..01d4694e14 100644 --- a/libavcodec/truemotion1.c +++ b/libavcodec/truemotion1.c @@ -34,6 +34,7 @@ #include #include "avcodec.h" +#include "internal.h" #include "libavutil/imgutils.h" #include "libavutil/internal.h" #include "libavutil/intreadwrite.h" @@ -401,8 +402,7 @@ static int truemotion1_decode_header(TrueMotion1Context *s) if (s->w != s->avctx->width || s->h != s->avctx->height || new_pix_fmt != s->avctx->pix_fmt) { - if (s->frame.data[0]) - s->avctx->release_buffer(s->avctx, &s->frame); + av_frame_unref(&s->frame); s->avctx->sample_aspect_ratio = (AVRational){ 1 << width_shift, 1 }; s->avctx->pix_fmt = new_pix_fmt; avcodec_set_dimensions(s->avctx, s->w, s->h); @@ -852,10 +852,7 @@ static int truemotion1_decode_frame(AVCodecContext *avctx, if ((ret = truemotion1_decode_header(s)) < 0) return ret; - s->frame.reference = 1; - s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | - FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE; - if ((ret = avctx->reget_buffer(avctx, &s->frame)) < 0) { + if ((ret = ff_reget_buffer(avctx, &s->frame)) < 0) { av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } @@ -866,8 +863,10 @@ static int truemotion1_decode_frame(AVCodecContext *avctx, truemotion1_decode_16bit(s); } + if ((ret = av_frame_ref(data, &s->frame)) < 0) + return ret; + *got_frame = 1; - *(AVFrame*)data = s->frame; /* report that the buffer was completely consumed */ return buf_size; @@ -877,9 +876,7 @@ static av_cold int truemotion1_decode_end(AVCodecContext *avctx) { TrueMotion1Context *s = avctx->priv_data; - if (s->frame.data[0]) - avctx->release_buffer(avctx, &s->frame); - + av_frame_unref(&s->frame); av_free(s->vert_pred); return 0; diff --git a/libavcodec/truemotion2.c b/libavcodec/truemotion2.c index d517906e43..2ecfb93161 100644 --- a/libavcodec/truemotion2.c +++ b/libavcodec/truemotion2.c @@ -28,6 +28,7 @@ #include "bytestream.h" #include "get_bits.h" #include "dsputil.h" +#include "internal.h" #define TM2_ESCAPE 0x80000000 #define TM2_DELTAS 64 @@ -847,9 +848,8 @@ static int decode_frame(AVCodecContext *avctx, av_log(avctx, AV_LOG_ERROR, "Cannot allocate temporary buffer\n"); return AVERROR(ENOMEM); } - p->reference = 1; - p->buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE; - if ((ret = avctx->reget_buffer(avctx, p)) < 0) { + + if ((ret = ff_reget_buffer(avctx, p)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); av_free(swbuf); return ret; @@ -883,10 +883,10 @@ static int decode_frame(AVCodecContext *avctx, l->cur = !l->cur; *got_frame = 1; - *(AVFrame*)data = l->pic; + ret = av_frame_ref(data, &l->pic); av_free(swbuf); - return buf_size; + return (ret < 0) ? ret : buf_size; } static av_cold int decode_init(AVCodecContext *avctx) @@ -968,8 +968,7 @@ static av_cold int decode_end(AVCodecContext *avctx) av_free(l->V2_base); } - if (pic->data[0]) - avctx->release_buffer(avctx, pic); + av_frame_unref(pic); return 0; } diff --git a/libavcodec/truespeech.c b/libavcodec/truespeech.c index 73f2de917f..859983c574 100644 --- a/libavcodec/truespeech.c +++ b/libavcodec/truespeech.c @@ -325,7 +325,7 @@ static int truespeech_decode_frame(AVCodecContext *avctx, void *data, /* get output buffer */ frame->nb_samples = iterations * 240; - if ((ret = ff_get_buffer(avctx, frame)) < 0) { + if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } diff --git a/libavcodec/tscc.c b/libavcodec/tscc.c index 0b3c7f1a60..ce88b0e754 100644 --- a/libavcodec/tscc.c +++ b/libavcodec/tscc.c @@ -47,7 +47,6 @@ typedef struct TsccContext { AVCodecContext *avctx; - AVFrame pic; // Bits per pixel int bpp; @@ -69,15 +68,11 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, int buf_size = avpkt->size; CamtasiaContext * const c = avctx->priv_data; const unsigned char *encoded = buf; + AVFrame *frame = data; int zret; // Zlib return code int ret, len = buf_size; - if(c->pic.data[0]) - avctx->release_buffer(avctx, &c->pic); - - c->pic.reference = 1; - c->pic.buffer_hints = FF_BUFFER_HINTS_VALID; - if ((ret = ff_get_buffer(avctx, &c->pic)) < 0){ + if ((ret = ff_get_buffer(avctx, frame, 0)) < 0){ av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } @@ -102,7 +97,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, if (zret != Z_DATA_ERROR) { bytestream2_init(&c->gb, c->decomp_buf, c->decomp_size - c->zstream.avail_out); - ff_msrle_decode(avctx, (AVPicture*)&c->pic, c->bpp, &c->gb); + ff_msrle_decode(avctx, (AVPicture*)frame, c->bpp, &c->gb); } /* make the palette available on the way out */ @@ -110,14 +105,13 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, const uint8_t *pal = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE, NULL); if (pal) { - c->pic.palette_has_changed = 1; + frame->palette_has_changed = 1; memcpy(c->pal, pal, AVPALETTE_SIZE); } - memcpy(c->pic.data[1], c->pal, AVPALETTE_SIZE); + memcpy(frame->data[1], c->pal, AVPALETTE_SIZE); } *got_frame = 1; - *(AVFrame*)data = c->pic; /* always report that the buffer was completely consumed */ return buf_size; @@ -174,8 +168,6 @@ static av_cold int decode_end(AVCodecContext *avctx) av_freep(&c->decomp_buf); - if (c->pic.data[0]) - avctx->release_buffer(avctx, &c->pic); inflateEnd(&c->zstream); return 0; diff --git a/libavcodec/tscc2.c b/libavcodec/tscc2.c index b7f1b8899b..439de91b40 100644 --- a/libavcodec/tscc2.c +++ b/libavcodec/tscc2.c @@ -28,6 +28,7 @@ #include "avcodec.h" #include "get_bits.h" #include "bytestream.h" +#include "internal.h" #include "tscc2data.h" typedef struct TSCC2Context { @@ -229,17 +230,15 @@ static int tscc2_decode_frame(AVCodecContext *avctx, void *data, return AVERROR_INVALIDDATA; } - c->pic.reference = 3; - c->pic.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | - FF_BUFFER_HINTS_REUSABLE; - if ((ret = avctx->reget_buffer(avctx, &c->pic)) < 0) { + if ((ret = ff_reget_buffer(avctx, &c->pic)) < 0) { av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); return ret; } if (frame_type == 0) { *got_frame = 1; - *(AVFrame*)data = c->pic; + if ((ret = av_frame_ref(data, &c->pic)) < 0) + return ret; return buf_size; } @@ -323,7 +322,8 @@ static int tscc2_decode_frame(AVCodecContext *avctx, void *data, } *got_frame = 1; - *(AVFrame*)data = c->pic; + if ((ret = av_frame_ref(data, &c->pic)) < 0) + return ret; /* always report that the buffer was completely consumed */ return buf_size; @@ -352,8 +352,6 @@ static av_cold int tscc2_decode_init(AVCodecContext *avctx) return AVERROR(ENOMEM); } - avctx->coded_frame = &c->pic; - return 0; } @@ -361,8 +359,7 @@ static av_cold int tscc2_decode_end(AVCodecContext *avctx) { TSCC2Context * const c = avctx->priv_data; - if (c->pic.data[0]) - avctx->release_buffer(avctx, &c->pic); + av_frame_unref(&c->pic); av_freep(&c->slice_quants); free_vlcs(c); diff --git a/libavcodec/tta.c b/libavcodec/tta.c index e230fafbf6..f8ad34f190 100644 --- a/libavcodec/tta.c +++ b/libavcodec/tta.c @@ -325,7 +325,7 @@ static int tta_decode_frame(AVCodecContext *avctx, void *data, /* get output buffer */ frame->nb_samples = framelen; - if ((ret = ff_get_buffer(avctx, frame)) < 0) { + if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } diff --git a/libavcodec/twinvq.c b/libavcodec/twinvq.c index 339808131e..a4c1e938e0 100644 --- a/libavcodec/twinvq.c +++ b/libavcodec/twinvq.c @@ -832,7 +832,7 @@ static int twin_decode_frame(AVCodecContext * avctx, void *data, /* get output buffer */ if (tctx->discarded_packets >= 2) { frame->nb_samples = mtab->size; - if ((ret = ff_get_buffer(avctx, frame)) < 0) { + if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } diff --git a/libavcodec/txd.c b/libavcodec/txd.c index fc6e32f1f3..a2d123e490 100644 --- a/libavcodec/txd.c +++ b/libavcodec/txd.c @@ -28,25 +28,10 @@ #include "internal.h" #include "s3tc.h" -typedef struct TXDContext { - AVFrame picture; -} TXDContext; - -static av_cold int txd_init(AVCodecContext *avctx) { - TXDContext *s = avctx->priv_data; - - avcodec_get_frame_defaults(&s->picture); - avctx->coded_frame = &s->picture; - - return 0; -} - static int txd_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { - TXDContext * const s = avctx->priv_data; GetByteContext gb; - AVFrame *picture = data; - AVFrame * const p = &s->picture; + AVFrame * const p = data; unsigned int version, w, h, d3d_format, depth, stride, flags; unsigned int y, v; uint8_t *ptr; @@ -78,14 +63,11 @@ static int txd_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, return AVERROR_PATCHWELCOME; } - if (p->data[0]) - avctx->release_buffer(avctx, p); - if ((ret = av_image_check_size(w, h, 0, avctx)) < 0) return ret; if (w != avctx->width || h != avctx->height) avcodec_set_dimensions(avctx, w, h); - if ((ret = ff_get_buffer(avctx, p)) < 0) { + if ((ret = ff_get_buffer(avctx, p, 0)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } @@ -135,7 +117,6 @@ static int txd_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, } } - *picture = s->picture; *got_frame = 1; return avpkt->size; @@ -145,22 +126,10 @@ unsupported: return AVERROR_PATCHWELCOME; } -static av_cold int txd_end(AVCodecContext *avctx) { - TXDContext *s = avctx->priv_data; - - if (s->picture.data[0]) - avctx->release_buffer(avctx, &s->picture); - - return 0; -} - AVCodec ff_txd_decoder = { .name = "txd", .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_TXD, - .priv_data_size = sizeof(TXDContext), - .init = txd_init, - .close = txd_end, .decode = txd_decode_frame, .capabilities = CODEC_CAP_DR1, .long_name = NULL_IF_CONFIG_SMALL("Renderware TXD (TeXture Dictionary) image"), diff --git a/libavcodec/ulti.c b/libavcodec/ulti.c index 275319605d..e99c26725b 100644 --- a/libavcodec/ulti.c +++ b/libavcodec/ulti.c @@ -30,6 +30,7 @@ #include "avcodec.h" #include "bytestream.h" +#include "internal.h" #include "ulti_cb.h" @@ -60,8 +61,7 @@ static av_cold int ulti_decode_end(AVCodecContext *avctx){ UltimotionDecodeContext *s = avctx->priv_data; AVFrame *pic = &s->frame; - if (pic->data[0]) - avctx->release_buffer(avctx, pic); + av_frame_unref(pic); return 0; } @@ -221,15 +221,13 @@ static int ulti_decode_frame(AVCodecContext *avctx, int blocks = 0; int done = 0; int x = 0, y = 0; - int i; + int i, ret; int skip; int tmp; - s->frame.reference = 1; - s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE; - if (avctx->reget_buffer(avctx, &s->frame) < 0) { + if ((ret = ff_reget_buffer(avctx, &s->frame)) < 0) { av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); - return -1; + return ret; } bytestream2_init(&s->gb, buf, buf_size); @@ -407,7 +405,8 @@ static int ulti_decode_frame(AVCodecContext *avctx, } *got_frame = 1; - *(AVFrame*)data= s->frame; + if ((ret = av_frame_ref(data, &s->frame)) < 0) + return ret; return buf_size; diff --git a/libavcodec/utils.c b/libavcodec/utils.c index 091d34c158..7e451bfa0b 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -30,6 +30,7 @@ #include "libavutil/avstring.h" #include "libavutil/channel_layout.h" #include "libavutil/crc.h" +#include "libavutil/frame.h" #include "libavutil/mathematics.h" #include "libavutil/pixdesc.h" #include "libavutil/imgutils.h" @@ -155,8 +156,6 @@ void avcodec_set_dimensions(AVCodecContext *s, int width, int height) s->height = height; } -#define INTERNAL_BUFFER_SIZE (32 + 1) - #if (ARCH_ARM && HAVE_NEON) || ARCH_PPC || HAVE_MMX # define STRIDE_ALIGN 16 #else @@ -304,87 +303,26 @@ int avcodec_fill_audio_frame(AVFrame *frame, int nb_channels, return ret; } -static int audio_get_buffer(AVCodecContext *avctx, AVFrame *frame) +static int update_frame_pool(AVCodecContext *avctx, AVFrame *frame) { - AVCodecInternal *avci = avctx->internal; - int buf_size, ret; + FramePool *pool = avctx->internal->pool; + int i, ret; - av_freep(&avci->audio_data); - buf_size = av_samples_get_buffer_size(NULL, avctx->channels, - frame->nb_samples, avctx->sample_fmt, - 0); - if (buf_size < 0) - return AVERROR(EINVAL); - - frame->data[0] = av_mallocz(buf_size); - if (!frame->data[0]) - return AVERROR(ENOMEM); - - ret = avcodec_fill_audio_frame(frame, avctx->channels, avctx->sample_fmt, - frame->data[0], buf_size, 0); - if (ret < 0) { - av_freep(&frame->data[0]); - return ret; - } - - avci->audio_data = frame->data[0]; - if (avctx->debug & FF_DEBUG_BUFFERS) - av_log(avctx, AV_LOG_DEBUG, "default_get_buffer called on frame %p, " - "internal audio buffer used\n", frame); - - return 0; -} - -static int video_get_buffer(AVCodecContext *s, AVFrame *pic) -{ - int i; - int w = s->width; - int h = s->height; - InternalBuffer *buf; - AVCodecInternal *avci = s->internal; - - if (pic->data[0] != NULL) { - av_log(s, AV_LOG_ERROR, "pic->data[0]!=NULL in avcodec_default_get_buffer\n"); - return -1; - } - if (avci->buffer_count >= INTERNAL_BUFFER_SIZE) { - av_log(s, AV_LOG_ERROR, "buffer_count overflow (missing release_buffer?)\n"); - return -1; - } - - if (av_image_check_size(w, h, 0, s)) - return -1; - - if (!avci->buffer) { - avci->buffer = av_mallocz((INTERNAL_BUFFER_SIZE + 1) * - sizeof(InternalBuffer)); - } - - buf = &avci->buffer[avci->buffer_count]; - - if (buf->base[0] && (buf->width != w || buf->height != h || buf->pix_fmt != s->pix_fmt)) { - for (i = 0; i < AV_NUM_DATA_POINTERS; i++) { - av_freep(&buf->base[i]); - buf->data[i] = NULL; - } - } - - if (!buf->base[0]) { - int h_chroma_shift, v_chroma_shift; - int size[4] = { 0 }; - int tmpsize; - int unaligned; + switch (avctx->codec_type) { + case AVMEDIA_TYPE_VIDEO: { AVPicture picture; - int stride_align[AV_NUM_DATA_POINTERS]; - const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(s->pix_fmt); - const int pixel_size = desc->comp[0].step_minus1 + 1; + int size[4] = { 0 }; + int w = frame->width; + int h = frame->height; + int tmpsize, unaligned; - av_pix_fmt_get_chroma_sub_sample(s->pix_fmt, &h_chroma_shift, - &v_chroma_shift); + if (pool->format == frame->format && + pool->width == frame->width && pool->height == frame->height) + return 0; - avcodec_align_dimensions2(s, &w, &h, stride_align); + avcodec_align_dimensions2(avctx, &w, &h, pool->stride_align); - if (!(s->flags & CODEC_FLAG_EMU_EDGE)) { + if (!(avctx->flags & CODEC_FLAG_EMU_EDGE)) { w += EDGE_WIDTH * 2; h += EDGE_WIDTH * 2; } @@ -392,16 +330,17 @@ static int video_get_buffer(AVCodecContext *s, AVFrame *pic) do { // NOTE: do not align linesizes individually, this breaks e.g. assumptions // that linesize[0] == 2*linesize[1] in the MPEG-encoder for 4:2:2 - av_image_fill_linesizes(picture.linesize, s->pix_fmt, w); + av_image_fill_linesizes(picture.linesize, avctx->pix_fmt, w); // increase alignment of w for next try (rhs gives the lowest bit set in w) w += w & ~(w - 1); unaligned = 0; for (i = 0; i < 4; i++) - unaligned |= picture.linesize[i] % stride_align[i]; + unaligned |= picture.linesize[i] % pool->stride_align[i]; } while (unaligned); - tmpsize = av_image_fill_pointers(picture.data, s->pix_fmt, h, NULL, picture.linesize); + tmpsize = av_image_fill_pointers(picture.data, avctx->pix_fmt, h, + NULL, picture.linesize); if (tmpsize < 0) return -1; @@ -409,54 +348,169 @@ static int video_get_buffer(AVCodecContext *s, AVFrame *pic) size[i] = picture.data[i + 1] - picture.data[i]; size[i] = tmpsize - (picture.data[i] - picture.data[0]); - memset(buf->base, 0, sizeof(buf->base)); - memset(buf->data, 0, sizeof(buf->data)); - - for (i = 0; i < 4 && size[i]; i++) { - const int h_shift = i == 0 ? 0 : h_chroma_shift; - const int v_shift = i == 0 ? 0 : v_chroma_shift; - - buf->linesize[i] = picture.linesize[i]; - - buf->base[i] = av_malloc(size[i] + 16); //FIXME 16 - if (buf->base[i] == NULL) - return -1; - - // no edge if EDGE EMU or not planar YUV - if ((s->flags & CODEC_FLAG_EMU_EDGE) || !size[2]) - buf->data[i] = buf->base[i]; - else - buf->data[i] = buf->base[i] + FFALIGN((buf->linesize[i] * EDGE_WIDTH >> v_shift) + (pixel_size * EDGE_WIDTH >> h_shift), stride_align[i]); + for (i = 0; i < 4; i++) { + av_buffer_pool_uninit(&pool->pools[i]); + pool->linesize[i] = picture.linesize[i]; + if (size[i]) { + pool->pools[i] = av_buffer_pool_init(size[i] + 16, NULL); + if (!pool->pools[i]) { + ret = AVERROR(ENOMEM); + goto fail; + } + } } - for (; i < AV_NUM_DATA_POINTERS; i++) { - buf->base[i] = buf->data[i] = NULL; - buf->linesize[i] = 0; + pool->format = frame->format; + pool->width = frame->width; + pool->height = frame->height; + + break; } - if (size[1] && !size[2]) - avpriv_set_systematic_pal2((uint32_t *)buf->data[1], s->pix_fmt); - buf->width = s->width; - buf->height = s->height; - buf->pix_fmt = s->pix_fmt; + case AVMEDIA_TYPE_AUDIO: { + int ch = av_get_channel_layout_nb_channels(frame->channel_layout); + int planar = av_sample_fmt_is_planar(frame->format); + int planes = planar ? ch : 1; + + if (pool->format == frame->format && pool->planes == planes && + pool->channels == ch && frame->nb_samples == pool->samples) + return 0; + + av_buffer_pool_uninit(&pool->pools[0]); + ret = av_samples_get_buffer_size(&pool->linesize[0], ch, + frame->nb_samples, frame->format, 0); + if (ret < 0) + goto fail; + + pool->pools[0] = av_buffer_pool_init(pool->linesize[0], NULL); + if (!pool->pools[0]) { + ret = AVERROR(ENOMEM); + goto fail; + } + + pool->format = frame->format; + pool->planes = planes; + pool->channels = ch; + pool->samples = frame->nb_samples; + break; + } + default: av_assert0(0); } - - for (i = 0; i < AV_NUM_DATA_POINTERS; i++) { - pic->base[i] = buf->base[i]; - pic->data[i] = buf->data[i]; - pic->linesize[i] = buf->linesize[i]; - } - pic->extended_data = pic->data; - avci->buffer_count++; - - if (s->debug & FF_DEBUG_BUFFERS) - av_log(s, AV_LOG_DEBUG, "default_get_buffer called on pic %p, %d " - "buffers used\n", pic, avci->buffer_count); - return 0; +fail: + for (i = 0; i < 4; i++) + av_buffer_pool_uninit(&pool->pools[i]); + pool->format = -1; + pool->planes = pool->channels = pool->samples = 0; + pool->width = pool->height = 0; + return ret; } -int avcodec_default_get_buffer(AVCodecContext *avctx, AVFrame *frame) +static int audio_get_buffer(AVCodecContext *avctx, AVFrame *frame) { + FramePool *pool = avctx->internal->pool; + int planes = pool->planes; + int i; + + frame->linesize[0] = pool->linesize[0]; + + if (planes > AV_NUM_DATA_POINTERS) { + frame->extended_data = av_mallocz(planes * sizeof(*frame->extended_data)); + frame->nb_extended_buf = planes - AV_NUM_DATA_POINTERS; + frame->extended_buf = av_mallocz(frame->nb_extended_buf * + sizeof(*frame->extended_buf)); + if (!frame->extended_data || !frame->extended_buf) { + av_freep(&frame->extended_data); + av_freep(&frame->extended_buf); + return AVERROR(ENOMEM); + } + } else + frame->extended_data = frame->data; + + for (i = 0; i < FFMIN(planes, AV_NUM_DATA_POINTERS); i++) { + frame->buf[i] = av_buffer_pool_get(pool->pools[0]); + if (!frame->buf[i]) + goto fail; + frame->extended_data[i] = frame->data[i] = frame->buf[i]->data; + } + for (i = 0; i < frame->nb_extended_buf; i++) { + frame->extended_buf[i] = av_buffer_pool_get(pool->pools[0]); + if (!frame->extended_buf[i]) + goto fail; + frame->extended_data[i + AV_NUM_DATA_POINTERS] = frame->extended_buf[i]->data; + } + + if (avctx->debug & FF_DEBUG_BUFFERS) + av_log(avctx, AV_LOG_DEBUG, "default_get_buffer called on frame %p", frame); + + return 0; +fail: + av_frame_unref(frame); + return AVERROR(ENOMEM); +} + +static int video_get_buffer(AVCodecContext *s, AVFrame *pic) +{ + FramePool *pool = s->internal->pool; + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pic->format); + int pixel_size = desc->comp[0].step_minus1 + 1; + int h_chroma_shift, v_chroma_shift; + int i; + + if (pic->data[0] != NULL) { + av_log(s, AV_LOG_ERROR, "pic->data[0]!=NULL in avcodec_default_get_buffer\n"); + return -1; + } + + memset(pic->data, 0, sizeof(pic->data)); + pic->extended_data = pic->data; + + av_pix_fmt_get_chroma_sub_sample(s->pix_fmt, &h_chroma_shift, &v_chroma_shift); + + for (i = 0; i < 4 && pool->pools[i]; i++) { + const int h_shift = i == 0 ? 0 : h_chroma_shift; + const int v_shift = i == 0 ? 0 : v_chroma_shift; + + pic->linesize[i] = pool->linesize[i]; + + pic->buf[i] = av_buffer_pool_get(pool->pools[i]); + if (!pic->buf[i]) + goto fail; + + // no edge if EDGE EMU or not planar YUV + if ((s->flags & CODEC_FLAG_EMU_EDGE) || !pool->pools[2]) + pic->data[i] = pic->buf[i]->data; + else { + pic->data[i] = pic->buf[i]->data + + FFALIGN((pic->linesize[i] * EDGE_WIDTH >> v_shift) + + (pixel_size * EDGE_WIDTH >> h_shift), pool->stride_align[i]); + } + } + for (; i < AV_NUM_DATA_POINTERS; i++) { + pic->data[i] = NULL; + pic->linesize[i] = 0; + } + if (pic->data[1] && !pic->data[2]) + avpriv_set_systematic_pal2((uint32_t *)pic->data[1], s->pix_fmt); + + if (s->debug & FF_DEBUG_BUFFERS) + av_log(s, AV_LOG_DEBUG, "default_get_buffer called on pic %p\n", pic); + + return 0; +fail: + av_frame_unref(pic); + return AVERROR(ENOMEM); +} + +int avcodec_default_get_buffer2(AVCodecContext *avctx, AVFrame *frame, int flags) +{ + int ret; + + if ((ret = update_frame_pool(avctx, frame)) < 0) + return ret; + +#if FF_API_GET_BUFFER frame->type = FF_BUFFER_TYPE_INTERNAL; +#endif + switch (avctx->codec_type) { case AVMEDIA_TYPE_VIDEO: return video_get_buffer(avctx, frame); @@ -467,14 +521,44 @@ int avcodec_default_get_buffer(AVCodecContext *avctx, AVFrame *frame) } } -int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame) +#if FF_API_GET_BUFFER +int avcodec_default_get_buffer(AVCodecContext *avctx, AVFrame *frame) { + return avcodec_default_get_buffer2(avctx, frame, 0); +} + +typedef struct CompatReleaseBufPriv { + AVCodecContext avctx; + AVFrame frame; +} CompatReleaseBufPriv; + +static void compat_free_buffer(void *opaque, uint8_t *data) +{ + CompatReleaseBufPriv *priv = opaque; + priv->avctx.release_buffer(&priv->avctx, &priv->frame); + av_freep(&priv); +} + +static void compat_release_buffer(void *opaque, uint8_t *data) +{ + AVBufferRef *buf = opaque; + av_buffer_unref(&buf); +} +#endif + +int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags) +{ + int ret; + switch (avctx->codec_type) { case AVMEDIA_TYPE_VIDEO: frame->width = avctx->width; frame->height = avctx->height; frame->format = avctx->pix_fmt; frame->sample_aspect_ratio = avctx->sample_aspect_ratio; + + if ((ret = av_image_check_size(avctx->width, avctx->height, 0, avctx)) < 0) + return ret; break; case AVMEDIA_TYPE_AUDIO: frame->sample_rate = avctx->sample_rate; @@ -487,86 +571,156 @@ int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame) frame->pkt_pts = avctx->pkt ? avctx->pkt->pts : AV_NOPTS_VALUE; frame->reordered_opaque = avctx->reordered_opaque; - return avctx->get_buffer(avctx, frame); +#if FF_API_GET_BUFFER + /* + * Wrap an old get_buffer()-allocated buffer in an bunch of AVBuffers. + * We wrap each plane in its own AVBuffer. Each of those has a reference to + * a dummy AVBuffer as its private data, unreffing it on free. + * When all the planes are freed, the dummy buffer's free callback calls + * release_buffer(). + */ + if (avctx->get_buffer) { + CompatReleaseBufPriv *priv = NULL; + AVBufferRef *dummy_buf = NULL; + int planes, i, ret; + + if (flags & AV_GET_BUFFER_FLAG_REF) + frame->reference = 1; + + ret = avctx->get_buffer(avctx, frame); + if (ret < 0) + return ret; + + /* return if the buffers are already set up + * this would happen e.g. when a custom get_buffer() calls + * avcodec_default_get_buffer + */ + if (frame->buf[0]) + return 0; + + priv = av_mallocz(sizeof(*priv)); + if (!priv) { + ret = AVERROR(ENOMEM); + goto fail; + } + priv->avctx = *avctx; + priv->frame = *frame; + + dummy_buf = av_buffer_create(NULL, 0, compat_free_buffer, priv, 0); + if (!dummy_buf) { + ret = AVERROR(ENOMEM); + goto fail; + } + +#define WRAP_PLANE(ref_out, data, data_size) \ +do { \ + AVBufferRef *dummy_ref = av_buffer_ref(dummy_buf); \ + if (!dummy_ref) { \ + ret = AVERROR(ENOMEM); \ + goto fail; \ + } \ + ref_out = av_buffer_create(data, data_size, compat_release_buffer, \ + dummy_ref, 0); \ + if (!ref_out) { \ + av_frame_unref(frame); \ + ret = AVERROR(ENOMEM); \ + goto fail; \ + } \ +} while (0) + + if (avctx->codec_type == AVMEDIA_TYPE_VIDEO) { + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(frame->format); + + if (!desc) { + ret = AVERROR(EINVAL); + goto fail; + } + planes = (desc->flags & PIX_FMT_PLANAR) ? desc->nb_components : 1; + + for (i = 0; i < planes; i++) { + int h_shift = (i == 1 || i == 2) ? desc->log2_chroma_h : 0; + int plane_size = (frame->width >> h_shift) * frame->linesize[i]; + + WRAP_PLANE(frame->buf[i], frame->data[i], plane_size); + } + } else { + int planar = av_sample_fmt_is_planar(frame->format); + planes = planar ? avctx->channels : 1; + + if (planes > FF_ARRAY_ELEMS(frame->buf)) { + frame->nb_extended_buf = planes - FF_ARRAY_ELEMS(frame->buf); + frame->extended_buf = av_malloc(sizeof(*frame->extended_buf) * + frame->nb_extended_buf); + if (!frame->extended_buf) { + ret = AVERROR(ENOMEM); + goto fail; + } + } + + for (i = 0; i < FFMIN(planes, FF_ARRAY_ELEMS(frame->buf)); i++) + WRAP_PLANE(frame->buf[i], frame->extended_data[i], frame->linesize[0]); + + for (i = 0; i < planes - FF_ARRAY_ELEMS(frame->buf); i++) + WRAP_PLANE(frame->extended_buf[i], + frame->extended_data[i + FF_ARRAY_ELEMS(frame->buf)], + frame->linesize[0]); + } + + av_buffer_unref(&dummy_buf); + + return 0; + +fail: + avctx->release_buffer(avctx, frame); + av_freep(&priv); + av_buffer_unref(&dummy_buf); + return ret; + } +#endif + + return avctx->get_buffer2(avctx, frame, flags); } -void avcodec_default_release_buffer(AVCodecContext *s, AVFrame *pic) +int ff_reget_buffer(AVCodecContext *avctx, AVFrame *frame) { - int i; - InternalBuffer *buf, *last; - AVCodecInternal *avci = s->internal; + AVFrame tmp; + int ret; - assert(s->codec_type == AVMEDIA_TYPE_VIDEO); + av_assert0(avctx->codec_type == AVMEDIA_TYPE_VIDEO); - assert(pic->type == FF_BUFFER_TYPE_INTERNAL); - assert(avci->buffer_count); + if (!frame->data[0]) + return ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF); - if (avci->buffer) { - buf = NULL; /* avoids warning */ - for (i = 0; i < avci->buffer_count; i++) { //just 3-5 checks so is not worth to optimize - buf = &avci->buffer[i]; - if (buf->data[0] == pic->data[0]) - break; - } - assert(i < avci->buffer_count); - avci->buffer_count--; - last = &avci->buffer[avci->buffer_count]; + if (av_frame_is_writable(frame)) + return 0; - if (buf != last) - FFSWAP(InternalBuffer, *buf, *last); + av_frame_move_ref(&tmp, frame); + + ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF); + if (ret < 0) { + av_frame_unref(&tmp); + return ret; } - for (i = 0; i < AV_NUM_DATA_POINTERS; i++) - pic->data[i] = NULL; -// pic->base[i]=NULL; + av_image_copy(frame->data, frame->linesize, tmp.data, tmp.linesize, + frame->format, frame->width, frame->height); - if (s->debug & FF_DEBUG_BUFFERS) - av_log(s, AV_LOG_DEBUG, "default_release_buffer called on pic %p, %d " - "buffers used\n", pic, avci->buffer_count); + av_frame_unref(&tmp); + + return 0; +} + +#if FF_API_GET_BUFFER +void avcodec_default_release_buffer(AVCodecContext *s, AVFrame *pic) +{ + av_frame_unref(pic); } int avcodec_default_reget_buffer(AVCodecContext *s, AVFrame *pic) { - AVFrame temp_pic; - int i; - - assert(s->codec_type == AVMEDIA_TYPE_VIDEO); - - /* If no picture return a new buffer */ - if (pic->data[0] == NULL) { - /* We will copy from buffer, so must be readable */ - pic->buffer_hints |= FF_BUFFER_HINTS_READABLE; - return ff_get_buffer(s, pic); - } - - assert(s->pix_fmt == pic->format); - - /* If internal buffer type return the same buffer */ - if (pic->type == FF_BUFFER_TYPE_INTERNAL) { - if (s->pkt) - pic->pkt_pts = s->pkt->pts; - else - pic->pkt_pts = AV_NOPTS_VALUE; - pic->reordered_opaque = s->reordered_opaque; - return 0; - } - - /* - * Not internal type and reget_buffer not overridden, emulate cr buffer - */ - temp_pic = *pic; - for (i = 0; i < AV_NUM_DATA_POINTERS; i++) - pic->data[i] = pic->base[i] = NULL; - pic->opaque = NULL; - /* Allocate new frame */ - if (ff_get_buffer(s, pic)) - return -1; - /* Copy image data from old buffer to new buffer */ - av_picture_copy((AVPicture *)pic, (AVPicture *)&temp_pic, s->pix_fmt, s->width, - s->height); - s->release_buffer(s, &temp_pic); // Release old frame - return 0; + av_assert0(0); } +#endif int avcodec_default_execute(AVCodecContext *c, int (*func)(AVCodecContext *c2, void *arg2), void *arg, int *ret, int count, int size) { @@ -691,6 +845,12 @@ int attribute_align_arg avcodec_open2(AVCodecContext *avctx, const AVCodec *code goto end; } + avctx->internal->pool = av_mallocz(sizeof(*avctx->internal->pool)); + if (!avctx->internal->pool) { + ret = AVERROR(ENOMEM); + goto free_and_end; + } + if (codec->priv_data_size > 0) { if (!avctx->priv_data) { avctx->priv_data = av_mallocz(codec->priv_data_size); @@ -876,6 +1036,8 @@ end: free_and_end: av_dict_free(&tmp); av_freep(&avctx->priv_data); + if (avctx->internal) + av_freep(&avctx->internal->pool); av_freep(&avctx->internal); avctx->codec = NULL; goto end; @@ -1279,6 +1441,7 @@ int attribute_align_arg avcodec_decode_video2(AVCodecContext *avctx, AVFrame *pi int *got_picture_ptr, AVPacket *avpkt) { + AVCodecInternal *avci = avctx->internal; int ret; *got_picture_ptr = 0; @@ -1290,6 +1453,9 @@ int attribute_align_arg avcodec_decode_video2(AVCodecContext *avctx, AVFrame *pi avcodec_get_frame_defaults(picture); + if (!avctx->refcounted_frames) + av_frame_unref(&avci->to_free); + if ((avctx->codec->capabilities & CODEC_CAP_DELAY) || avpkt->size || (avctx->active_thread_type & FF_THREAD_FRAME)) { if (HAVE_THREADS && avctx->active_thread_type & FF_THREAD_FRAME) ret = ff_thread_decode_frame(avctx, picture, got_picture_ptr, @@ -1309,8 +1475,17 @@ int attribute_align_arg avcodec_decode_video2(AVCodecContext *avctx, AVFrame *pi emms_c(); //needed to avoid an emms_c() call before every return; - if (*got_picture_ptr) + if (ret < 0 && picture->data[0]) + av_frame_unref(picture); + + if (*got_picture_ptr) { + if (!avctx->refcounted_frames) { + avci->to_free = *picture; + avci->to_free.extended_data = avci->to_free.data; + } + avctx->frame_number++; + } } else ret = 0; @@ -1374,6 +1549,7 @@ int attribute_align_arg avcodec_decode_audio4(AVCodecContext *avctx, int *got_frame_ptr, AVPacket *avpkt) { + AVCodecInternal *avci = avctx->internal; int planar, channels; int ret = 0; @@ -1390,6 +1566,9 @@ int attribute_align_arg avcodec_decode_audio4(AVCodecContext *avctx, avcodec_get_frame_defaults(frame); + if (!avctx->refcounted_frames) + av_frame_unref(&avci->to_free); + if ((avctx->codec->capabilities & CODEC_CAP_DELAY) || avpkt->size) { ret = avctx->codec->decode(avctx, frame, got_frame_ptr, avpkt); if (ret >= 0 && *got_frame_ptr) { @@ -1397,7 +1576,15 @@ int attribute_align_arg avcodec_decode_audio4(AVCodecContext *avctx, frame->pkt_dts = avpkt->dts; if (frame->format == AV_SAMPLE_FMT_NONE) frame->format = avctx->sample_fmt; + + if (!avctx->refcounted_frames) { + avci->to_free = *frame; + avci->to_free.extended_data = avci->to_free.data; + } } + + if (ret < 0 && frame->data[0]) + av_frame_unref(frame); } /* many decoders assign whole AVFrames, thus overwriting extended_data; @@ -1460,12 +1647,18 @@ av_cold int avcodec_close(AVCodecContext *avctx) } if (avcodec_is_open(avctx)) { + FramePool *pool = avctx->internal->pool; + int i; if (HAVE_THREADS && avctx->thread_opaque) ff_thread_free(avctx); if (avctx->codec && avctx->codec->close) avctx->codec->close(avctx); - avcodec_default_free_buffers(avctx); avctx->coded_frame = NULL; + if (!avctx->refcounted_frames) + av_frame_unref(&avctx->internal->to_free); + for (i = 0; i < FF_ARRAY_ELEMS(pool->pools); i++) + av_buffer_pool_uninit(&pool->pools[i]); + av_freep(&avctx->internal->pool); av_freep(&avctx->internal); } @@ -1739,49 +1932,6 @@ void avcodec_flush_buffers(AVCodecContext *avctx) avctx->codec->flush(avctx); } -static void video_free_buffers(AVCodecContext *s) -{ - AVCodecInternal *avci = s->internal; - int i, j; - - if (!avci->buffer) - return; - - if (avci->buffer_count) - av_log(s, AV_LOG_WARNING, "Found %i unreleased buffers!\n", - avci->buffer_count); - for (i = 0; i < INTERNAL_BUFFER_SIZE; i++) { - InternalBuffer *buf = &avci->buffer[i]; - for (j = 0; j < 4; j++) { - av_freep(&buf->base[j]); - buf->data[j] = NULL; - } - } - av_freep(&avci->buffer); - - avci->buffer_count = 0; -} - -static void audio_free_buffers(AVCodecContext *avctx) -{ - AVCodecInternal *avci = avctx->internal; - av_freep(&avci->audio_data); -} - -void avcodec_default_free_buffers(AVCodecContext *avctx) -{ - switch (avctx->codec_type) { - case AVMEDIA_TYPE_VIDEO: - video_free_buffers(avctx); - break; - case AVMEDIA_TYPE_AUDIO: - audio_free_buffers(avctx); - break; - default: - break; - } -} - int av_get_exact_bits_per_sample(enum AVCodecID codec_id) { switch (codec_id) { @@ -2117,17 +2267,36 @@ unsigned int avpriv_toupper4(unsigned int x) (av_toupper((x >> 24) & 0xFF) << 24); } +int ff_thread_ref_frame(ThreadFrame *dst, ThreadFrame *src) +{ + int ret; + + dst->owner = src->owner; + + ret = av_frame_ref(dst->f, src->f); + if (ret < 0) + return ret; + + if (src->progress && + !(dst->progress = av_buffer_ref(src->progress))) { + ff_thread_release_buffer(dst->owner, dst); + return AVERROR(ENOMEM); + } + + return 0; +} + #if !HAVE_THREADS -int ff_thread_get_buffer(AVCodecContext *avctx, AVFrame *f) +int ff_thread_get_buffer(AVCodecContext *avctx, AVFrame *f, int flags) { f->owner = avctx; - return ff_get_buffer(avctx, f); + return ff_get_buffer(avctx, f, flags); } void ff_thread_release_buffer(AVCodecContext *avctx, AVFrame *f) { - f->owner->release_buffer(f->owner, f); + av_frame_unref(f); } void ff_thread_finish_setup(AVCodecContext *avctx) diff --git a/libavcodec/utvideo.h b/libavcodec/utvideo.h index 0d7664c822..0a1317e807 100644 --- a/libavcodec/utvideo.h +++ b/libavcodec/utvideo.h @@ -65,7 +65,6 @@ extern const int ff_ut_rgb_order[4]; typedef struct UtvideoContext { AVCodecContext *avctx; - AVFrame pic; DSPContext dsp; uint32_t frame_info_size, flags, frame_info; diff --git a/libavcodec/utvideodec.c b/libavcodec/utvideodec.c index 3f8f690ee0..06f3108eeb 100644 --- a/libavcodec/utvideodec.c +++ b/libavcodec/utvideodec.c @@ -331,13 +331,9 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, int plane_size, max_slice_size = 0, slice_start, slice_end, slice_size; int ret; GetByteContext gb; + ThreadFrame frame = { .f = data }; - if (c->pic.data[0]) - ff_thread_release_buffer(avctx, &c->pic); - - c->pic.reference = 1; - c->pic.buffer_hints = FF_BUFFER_HINTS_VALID; - if ((ret = ff_thread_get_buffer(avctx, &c->pic)) < 0) { + if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } @@ -396,42 +392,42 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, case AV_PIX_FMT_RGB24: case AV_PIX_FMT_RGBA: for (i = 0; i < c->planes; i++) { - ret = decode_plane(c, i, c->pic.data[0] + ff_ut_rgb_order[i], - c->planes, c->pic.linesize[0], avctx->width, + ret = decode_plane(c, i, frame.f->data[0] + ff_ut_rgb_order[i], + c->planes, frame.f->linesize[0], avctx->width, avctx->height, plane_start[i], c->frame_pred == PRED_LEFT); if (ret) return ret; if (c->frame_pred == PRED_MEDIAN) { if (!c->interlaced) { - restore_median(c->pic.data[0] + ff_ut_rgb_order[i], - c->planes, c->pic.linesize[0], avctx->width, + restore_median(frame.f->data[0] + ff_ut_rgb_order[i], + c->planes, frame.f->linesize[0], avctx->width, avctx->height, c->slices, 0); } else { - restore_median_il(c->pic.data[0] + ff_ut_rgb_order[i], - c->planes, c->pic.linesize[0], + restore_median_il(frame.f->data[0] + ff_ut_rgb_order[i], + c->planes, frame.f->linesize[0], avctx->width, avctx->height, c->slices, 0); } } } - restore_rgb_planes(c->pic.data[0], c->planes, c->pic.linesize[0], + restore_rgb_planes(frame.f->data[0], c->planes, frame.f->linesize[0], avctx->width, avctx->height); break; case AV_PIX_FMT_YUV420P: for (i = 0; i < 3; i++) { - ret = decode_plane(c, i, c->pic.data[i], 1, c->pic.linesize[i], + ret = decode_plane(c, i, frame.f->data[i], 1, frame.f->linesize[i], avctx->width >> !!i, avctx->height >> !!i, plane_start[i], c->frame_pred == PRED_LEFT); if (ret) return ret; if (c->frame_pred == PRED_MEDIAN) { if (!c->interlaced) { - restore_median(c->pic.data[i], 1, c->pic.linesize[i], + restore_median(frame.f->data[i], 1, frame.f->linesize[i], avctx->width >> !!i, avctx->height >> !!i, c->slices, !i); } else { - restore_median_il(c->pic.data[i], 1, c->pic.linesize[i], + restore_median_il(frame.f->data[i], 1, frame.f->linesize[i], avctx->width >> !!i, avctx->height >> !!i, c->slices, !i); @@ -441,18 +437,18 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, break; case AV_PIX_FMT_YUV422P: for (i = 0; i < 3; i++) { - ret = decode_plane(c, i, c->pic.data[i], 1, c->pic.linesize[i], + ret = decode_plane(c, i, frame.f->data[i], 1, frame.f->linesize[i], avctx->width >> !!i, avctx->height, plane_start[i], c->frame_pred == PRED_LEFT); if (ret) return ret; if (c->frame_pred == PRED_MEDIAN) { if (!c->interlaced) { - restore_median(c->pic.data[i], 1, c->pic.linesize[i], + restore_median(frame.f->data[i], 1, frame.f->linesize[i], avctx->width >> !!i, avctx->height, c->slices, 0); } else { - restore_median_il(c->pic.data[i], 1, c->pic.linesize[i], + restore_median_il(frame.f->data[i], 1, frame.f->linesize[i], avctx->width >> !!i, avctx->height, c->slices, 0); } @@ -461,12 +457,11 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, break; } - c->pic.key_frame = 1; - c->pic.pict_type = AV_PICTURE_TYPE_I; - c->pic.interlaced_frame = !!c->interlaced; + frame.f->key_frame = 1; + frame.f->pict_type = AV_PICTURE_TYPE_I; + frame.f->interlaced_frame = !!c->interlaced; - *got_frame = 1; - *(AVFrame*)data = c->pic; + *got_frame = 1; /* always report that the buffer was completely consumed */ return buf_size; @@ -534,9 +529,6 @@ static av_cold int decode_end(AVCodecContext *avctx) { UtvideoContext * const c = avctx->priv_data; - if (c->pic.data[0]) - ff_thread_release_buffer(avctx, &c->pic); - av_freep(&c->slice_bits); return 0; diff --git a/libavcodec/v210dec.c b/libavcodec/v210dec.c index 2a6aa61376..b8b647e6f6 100644 --- a/libavcodec/v210dec.c +++ b/libavcodec/v210dec.c @@ -36,10 +36,6 @@ static av_cold int decode_init(AVCodecContext *avctx) avctx->pix_fmt = AV_PIX_FMT_YUV422P10; avctx->bits_per_raw_sample = 10; - avctx->coded_frame = avcodec_alloc_frame(); - if (!avctx->coded_frame) - return AVERROR(ENOMEM); - return 0; } @@ -47,22 +43,18 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { int h, w, ret; - AVFrame *pic = avctx->coded_frame; + AVFrame *pic = data; const uint8_t *psrc = avpkt->data; uint16_t *y, *u, *v; int aligned_width = ((avctx->width + 47) / 48) * 48; int stride = aligned_width * 8 / 3; - if (pic->data[0]) - avctx->release_buffer(avctx, pic); - if (avpkt->size < stride * avctx->height) { av_log(avctx, AV_LOG_ERROR, "packet too small\n"); return AVERROR_INVALIDDATA; } - pic->reference = 0; - if ((ret = ff_get_buffer(avctx, pic)) < 0) + if ((ret = ff_get_buffer(avctx, pic, 0)) < 0) return ret; y = (uint16_t*)pic->data[0]; @@ -110,27 +102,15 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, } *got_frame = 1; - *(AVFrame*)data = *avctx->coded_frame; return avpkt->size; } -static av_cold int decode_close(AVCodecContext *avctx) -{ - AVFrame *pic = avctx->coded_frame; - if (pic->data[0]) - avctx->release_buffer(avctx, pic); - av_freep(&avctx->coded_frame); - - return 0; -} - AVCodec ff_v210_decoder = { .name = "v210", .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_V210, .init = decode_init, - .close = decode_close, .decode = decode_frame, .capabilities = CODEC_CAP_DR1, .long_name = NULL_IF_CONFIG_SMALL("Uncompressed 4:2:2 10-bit"), diff --git a/libavcodec/v210x.c b/libavcodec/v210x.c index 97938b1090..758294c5bb 100644 --- a/libavcodec/v210x.c +++ b/libavcodec/v210x.c @@ -33,8 +33,6 @@ static av_cold int decode_init(AVCodecContext *avctx) avctx->pix_fmt = AV_PIX_FMT_YUV422P16; avctx->bits_per_raw_sample = 10; - avctx->coded_frame= avcodec_alloc_frame(); - return 0; } @@ -42,15 +40,12 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { const uint32_t *src = (const uint32_t *)avpkt->data; - AVFrame *pic = avctx->coded_frame; + AVFrame *pic = data; int width = avctx->width; int y = 0; uint16_t *ydst, *udst, *vdst, *yend; int ret; - if (pic->data[0]) - avctx->release_buffer(avctx, pic); - if (avpkt->size < avctx->width * avctx->height * 8 / 3) { av_log(avctx, AV_LOG_ERROR, "Packet too small\n"); return AVERROR_INVALIDDATA; @@ -60,8 +55,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, av_log_ask_for_sample(avctx, "Probably padded data\n"); } - pic->reference = 0; - if ((ret = ff_get_buffer(avctx, pic)) < 0) + if ((ret = ff_get_buffer(avctx, pic, 0)) < 0) return ret; ydst = (uint16_t *)pic->data[0]; @@ -122,27 +116,15 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, } *got_frame = 1; - *(AVFrame*)data= *avctx->coded_frame; return avpkt->size; } -static av_cold int decode_close(AVCodecContext *avctx) -{ - AVFrame *pic = avctx->coded_frame; - if (pic->data[0]) - avctx->release_buffer(avctx, pic); - av_freep(&avctx->coded_frame); - - return 0; -} - AVCodec ff_v210x_decoder = { .name = "v210x", .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_V210X, .init = decode_init, - .close = decode_close, .decode = decode_frame, .capabilities = CODEC_CAP_DR1, .long_name = NULL_IF_CONFIG_SMALL("Uncompressed 4:2:2 10-bit"), diff --git a/libavcodec/v410dec.c b/libavcodec/v410dec.c index efd2093134..e4b2a7ded3 100644 --- a/libavcodec/v410dec.c +++ b/libavcodec/v410dec.c @@ -39,36 +39,24 @@ static av_cold int v410_decode_init(AVCodecContext *avctx) } } - avctx->coded_frame = avcodec_alloc_frame(); - - if (!avctx->coded_frame) { - av_log(avctx, AV_LOG_ERROR, "Could not allocate frame.\n"); - return AVERROR(ENOMEM); - } - return 0; } static int v410_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { - AVFrame *pic = avctx->coded_frame; + AVFrame *pic = data; uint8_t *src = avpkt->data; uint16_t *y, *u, *v; uint32_t val; int i, j; - if (pic->data[0]) - avctx->release_buffer(avctx, pic); - if (avpkt->size < 4 * avctx->height * avctx->width) { av_log(avctx, AV_LOG_ERROR, "Insufficient input data.\n"); return AVERROR(EINVAL); } - pic->reference = 0; - - if (ff_get_buffer(avctx, pic) < 0) { + if (ff_get_buffer(avctx, pic, 0) < 0) { av_log(avctx, AV_LOG_ERROR, "Could not allocate buffer.\n"); return AVERROR(ENOMEM); } @@ -97,28 +85,16 @@ static int v410_decode_frame(AVCodecContext *avctx, void *data, } *got_frame = 1; - *(AVFrame *)data = *pic; return avpkt->size; } -static av_cold int v410_decode_close(AVCodecContext *avctx) -{ - if (avctx->coded_frame->data[0]) - avctx->release_buffer(avctx, avctx->coded_frame); - - av_freep(&avctx->coded_frame); - - return 0; -} - AVCodec ff_v410_decoder = { .name = "v410", .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_V410, .init = v410_decode_init, .decode = v410_decode_frame, - .close = v410_decode_close, .capabilities = CODEC_CAP_DR1, .long_name = NULL_IF_CONFIG_SMALL("Uncompressed 4:4:4 10-bit"), }; diff --git a/libavcodec/vaapi_h264.c b/libavcodec/vaapi_h264.c index f34982cc73..7cbe8c1826 100644 --- a/libavcodec/vaapi_h264.c +++ b/libavcodec/vaapi_h264.c @@ -55,7 +55,7 @@ static void fill_vaapi_pic(VAPictureH264 *va_pic, int pic_structure) { if (pic_structure == 0) - pic_structure = pic->f.reference; + pic_structure = pic->reference; pic_structure &= PICT_FRAME; /* PICT_TOP_FIELD|PICT_BOTTOM_FIELD */ va_pic->picture_id = ff_vaapi_get_surface_id(pic); @@ -64,7 +64,7 @@ static void fill_vaapi_pic(VAPictureH264 *va_pic, va_pic->flags = 0; if (pic_structure != PICT_FRAME) va_pic->flags |= (pic_structure & PICT_TOP_FIELD) ? VA_PICTURE_H264_TOP_FIELD : VA_PICTURE_H264_BOTTOM_FIELD; - if (pic->f.reference) + if (pic->reference) va_pic->flags |= pic->long_ref ? VA_PICTURE_H264_LONG_TERM_REFERENCE : VA_PICTURE_H264_SHORT_TERM_REFERENCE; va_pic->TopFieldOrderCnt = 0; @@ -134,13 +134,13 @@ static int fill_vaapi_ReferenceFrames(VAPictureParameterBufferH264 *pic_param, for (i = 0; i < h->short_ref_count; i++) { Picture * const pic = h->short_ref[i]; - if (pic && pic->f.reference && dpb_add(&dpb, pic) < 0) + if (pic && pic->reference && dpb_add(&dpb, pic) < 0) return -1; } for (i = 0; i < 16; i++) { Picture * const pic = h->long_ref[i]; - if (pic && pic->f.reference && dpb_add(&dpb, pic) < 0) + if (pic && pic->reference && dpb_add(&dpb, pic) < 0) return -1; } return 0; @@ -160,7 +160,7 @@ static void fill_vaapi_RefPicList(VAPictureH264 RefPicList[32], { unsigned int i, n = 0; for (i = 0; i < ref_count; i++) - if (ref_list[i].f.reference) + if (ref_list[i].reference) fill_vaapi_pic(&RefPicList[n++], &ref_list[i], 0); for (; n < 32; n++) diff --git a/libavcodec/vb.c b/libavcodec/vb.c index 8bb1a70cc1..df0fef98d2 100644 --- a/libavcodec/vb.c +++ b/libavcodec/vb.c @@ -41,7 +41,6 @@ enum VBFlags { typedef struct VBDecContext { AVCodecContext *avctx; - AVFrame pic; uint8_t *frame, *prev_frame; uint32_t pal[AVPALETTE_COUNT]; @@ -189,6 +188,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { VBDecContext * const c = avctx->priv_data; + AVFrame *frame = data; uint8_t *outptr, *srcptr; int i, j, ret; int flags; @@ -197,10 +197,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, bytestream2_init(&c->stream, avpkt->data, avpkt->size); - if (c->pic.data[0]) - avctx->release_buffer(avctx, &c->pic); - c->pic.reference = 1; - if ((ret = ff_get_buffer(avctx, &c->pic)) < 0) { + if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } @@ -222,22 +219,21 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, vb_decode_palette(c, size); } - memcpy(c->pic.data[1], c->pal, AVPALETTE_SIZE); - c->pic.palette_has_changed = flags & VB_HAS_PALETTE; + memcpy(frame->data[1], c->pal, AVPALETTE_SIZE); + frame->palette_has_changed = flags & VB_HAS_PALETTE; - outptr = c->pic.data[0]; + outptr = frame->data[0]; srcptr = c->frame; for (i = 0; i < avctx->height; i++) { memcpy(outptr, srcptr, avctx->width); srcptr += avctx->width; - outptr += c->pic.linesize[0]; + outptr += frame->linesize[0]; } FFSWAP(uint8_t*, c->frame, c->prev_frame); *got_frame = 1; - *(AVFrame*)data = c->pic; /* always report that the buffer was completely consumed */ return avpkt->size; @@ -262,8 +258,6 @@ static av_cold int decode_end(AVCodecContext *avctx) av_freep(&c->frame); av_freep(&c->prev_frame); - if(c->pic.data[0]) - avctx->release_buffer(avctx, &c->pic); return 0; } diff --git a/libavcodec/vble.c b/libavcodec/vble.c index 228b1bd61a..6cd2dfc2e5 100644 --- a/libavcodec/vble.c +++ b/libavcodec/vble.c @@ -84,10 +84,10 @@ static int vble_unpack(VBLEContext *ctx, GetBitContext *gb) return 0; } -static void vble_restore_plane(VBLEContext *ctx, int plane, int offset, - int width, int height) +static void vble_restore_plane(VBLEContext *ctx, AVFrame *pic, + int plane, int offset, + int width, int height) { - AVFrame *pic = ctx->avctx->coded_frame; uint8_t *dst = pic->data[plane]; uint8_t *val = ctx->val + offset; int stride = pic->linesize[plane]; @@ -116,21 +116,15 @@ static int vble_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { VBLEContext *ctx = avctx->priv_data; - AVFrame *pic = avctx->coded_frame; + AVFrame *pic = data; GetBitContext gb; const uint8_t *src = avpkt->data; int version; int offset = 0; int width_uv = avctx->width / 2, height_uv = avctx->height / 2; - pic->reference = 0; - - /* Clear buffer if need be */ - if (pic->data[0]) - avctx->release_buffer(avctx, pic); - /* Allocate buffer */ - if (ff_get_buffer(avctx, pic) < 0) { + if (ff_get_buffer(avctx, pic, 0) < 0) { av_log(avctx, AV_LOG_ERROR, "Could not allocate buffer.\n"); return AVERROR(ENOMEM); } @@ -154,19 +148,18 @@ static int vble_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, } /* Restore planes. Should be almost identical to Huffyuv's. */ - vble_restore_plane(ctx, 0, offset, avctx->width, avctx->height); + vble_restore_plane(ctx, pic, 0, offset, avctx->width, avctx->height); /* Chroma */ if (!(ctx->avctx->flags & CODEC_FLAG_GRAY)) { offset += avctx->width * avctx->height; - vble_restore_plane(ctx, 1, offset, width_uv, height_uv); + vble_restore_plane(ctx, pic, 1, offset, width_uv, height_uv); offset += width_uv * height_uv; - vble_restore_plane(ctx, 2, offset, width_uv, height_uv); + vble_restore_plane(ctx, pic, 2, offset, width_uv, height_uv); } *got_frame = 1; - *(AVFrame *)data = *pic; return avpkt->size; } @@ -174,12 +167,6 @@ static int vble_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, static av_cold int vble_decode_close(AVCodecContext *avctx) { VBLEContext *ctx = avctx->priv_data; - AVFrame *pic = avctx->coded_frame; - - if (pic->data[0]) - avctx->release_buffer(avctx, pic); - - av_freep(&avctx->coded_frame); av_freep(&ctx->val); return 0; @@ -195,12 +182,6 @@ static av_cold int vble_decode_init(AVCodecContext *avctx) avctx->pix_fmt = AV_PIX_FMT_YUV420P; avctx->bits_per_raw_sample = 8; - avctx->coded_frame = avcodec_alloc_frame(); - - if (!avctx->coded_frame) { - av_log(avctx, AV_LOG_ERROR, "Could not allocate frame.\n"); - return AVERROR(ENOMEM); - } ctx->size = avpicture_get_size(avctx->pix_fmt, avctx->width, avctx->height); diff --git a/libavcodec/vc1dec.c b/libavcodec/vc1dec.c index adfd699ac8..44dd652283 100644 --- a/libavcodec/vc1dec.c +++ b/libavcodec/vc1dec.c @@ -348,8 +348,8 @@ static void vc1_mc_1mv(VC1Context *v, int dir) // store motion vectors for further use in B frames if (s->pict_type == AV_PICTURE_TYPE_P) { - s->current_picture.f.motion_val[1][s->block_index[0] + v->blocks_off][0] = mx; - s->current_picture.f.motion_val[1][s->block_index[0] + v->blocks_off][1] = my; + s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][0] = mx; + s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][1] = my; } uvmx = (mx + ((mx & 3) == 3)) >> 1; @@ -604,8 +604,8 @@ static void vc1_mc_4mv_luma(VC1Context *v, int n, int dir) ty = (chosen_mv[f][0][1] + chosen_mv[f][1][1]) / 2; break; } - s->current_picture.f.motion_val[1][s->block_index[0] + v->blocks_off][0] = tx; - s->current_picture.f.motion_val[1][s->block_index[0] + v->blocks_off][1] = ty; + s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][0] = tx; + s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][1] = ty; for (k = 0; k < 4; k++) v->mv_f[1][s->block_index[k] + v->blocks_off] = f; } @@ -798,8 +798,8 @@ static void vc1_mc_4mv_chroma(VC1Context *v, int dir) valid_count = get_chroma_mv(mvx, mvy, intra, 0, &tx, &ty); chroma_ref_type = v->reffield; if (!valid_count) { - s->current_picture.f.motion_val[1][s->block_index[0] + v->blocks_off][0] = 0; - s->current_picture.f.motion_val[1][s->block_index[0] + v->blocks_off][1] = 0; + s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][0] = 0; + s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][1] = 0; v->luma_mv[s->mb_x][0] = v->luma_mv[s->mb_x][1] = 0; return; //no need to do MC for intra blocks } @@ -813,8 +813,8 @@ static void vc1_mc_4mv_chroma(VC1Context *v, int dir) } if (v->field_mode && chroma_ref_type == 1 && v->cur_field_type == 1 && !v->s.last_picture.f.data[0]) return; - s->current_picture.f.motion_val[1][s->block_index[0] + v->blocks_off][0] = tx; - s->current_picture.f.motion_val[1][s->block_index[0] + v->blocks_off][1] = ty; + s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][0] = tx; + s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][1] = ty; uvmx = (tx + ((tx & 3) == 3)) >> 1; uvmy = (ty + ((ty & 3) == 3)) >> 1; @@ -1376,30 +1376,30 @@ static inline void vc1_pred_mv(VC1Context *v, int n, int dmv_x, int dmv_y, xy = s->block_index[n]; if (s->mb_intra) { - s->mv[0][n][0] = s->current_picture.f.motion_val[0][xy + v->blocks_off][0] = 0; - s->mv[0][n][1] = s->current_picture.f.motion_val[0][xy + v->blocks_off][1] = 0; - s->current_picture.f.motion_val[1][xy + v->blocks_off][0] = 0; - s->current_picture.f.motion_val[1][xy + v->blocks_off][1] = 0; + s->mv[0][n][0] = s->current_picture.motion_val[0][xy + v->blocks_off][0] = 0; + s->mv[0][n][1] = s->current_picture.motion_val[0][xy + v->blocks_off][1] = 0; + s->current_picture.motion_val[1][xy + v->blocks_off][0] = 0; + s->current_picture.motion_val[1][xy + v->blocks_off][1] = 0; if (mv1) { /* duplicate motion data for 1-MV block */ - s->current_picture.f.motion_val[0][xy + 1 + v->blocks_off][0] = 0; - s->current_picture.f.motion_val[0][xy + 1 + v->blocks_off][1] = 0; - s->current_picture.f.motion_val[0][xy + wrap + v->blocks_off][0] = 0; - s->current_picture.f.motion_val[0][xy + wrap + v->blocks_off][1] = 0; - s->current_picture.f.motion_val[0][xy + wrap + 1 + v->blocks_off][0] = 0; - s->current_picture.f.motion_val[0][xy + wrap + 1 + v->blocks_off][1] = 0; + s->current_picture.motion_val[0][xy + 1 + v->blocks_off][0] = 0; + s->current_picture.motion_val[0][xy + 1 + v->blocks_off][1] = 0; + s->current_picture.motion_val[0][xy + wrap + v->blocks_off][0] = 0; + s->current_picture.motion_val[0][xy + wrap + v->blocks_off][1] = 0; + s->current_picture.motion_val[0][xy + wrap + 1 + v->blocks_off][0] = 0; + s->current_picture.motion_val[0][xy + wrap + 1 + v->blocks_off][1] = 0; v->luma_mv[s->mb_x][0] = v->luma_mv[s->mb_x][1] = 0; - s->current_picture.f.motion_val[1][xy + 1 + v->blocks_off][0] = 0; - s->current_picture.f.motion_val[1][xy + 1 + v->blocks_off][1] = 0; - s->current_picture.f.motion_val[1][xy + wrap][0] = 0; - s->current_picture.f.motion_val[1][xy + wrap + v->blocks_off][1] = 0; - s->current_picture.f.motion_val[1][xy + wrap + 1 + v->blocks_off][0] = 0; - s->current_picture.f.motion_val[1][xy + wrap + 1 + v->blocks_off][1] = 0; + s->current_picture.motion_val[1][xy + 1 + v->blocks_off][0] = 0; + s->current_picture.motion_val[1][xy + 1 + v->blocks_off][1] = 0; + s->current_picture.motion_val[1][xy + wrap][0] = 0; + s->current_picture.motion_val[1][xy + wrap + v->blocks_off][1] = 0; + s->current_picture.motion_val[1][xy + wrap + 1 + v->blocks_off][0] = 0; + s->current_picture.motion_val[1][xy + wrap + 1 + v->blocks_off][1] = 0; } return; } - C = s->current_picture.f.motion_val[dir][xy - 1 + v->blocks_off]; - A = s->current_picture.f.motion_val[dir][xy - wrap + v->blocks_off]; + C = s->current_picture.motion_val[dir][xy - 1 + v->blocks_off]; + A = s->current_picture.motion_val[dir][xy - wrap + v->blocks_off]; if (mv1) { if (v->field_mode && mixedmv_pic) off = (s->mb_x == (s->mb_width - 1)) ? -2 : 2; @@ -1421,7 +1421,7 @@ static inline void vc1_pred_mv(VC1Context *v, int n, int dmv_x, int dmv_y, off = -1; } } - B = s->current_picture.f.motion_val[dir][xy - wrap + off + v->blocks_off]; + B = s->current_picture.motion_val[dir][xy - wrap + off + v->blocks_off]; a_valid = !s->first_slice_line || (n == 2 || n == 3); b_valid = a_valid && (s->mb_width > 1); @@ -1584,15 +1584,15 @@ static inline void vc1_pred_mv(VC1Context *v, int n, int dmv_x, int dmv_y, if (v->field_mode && v->cur_field_type && v->ref_field_type[dir] == 0) y_bias = 1; /* store MV using signed modulus of MV range defined in 4.11 */ - s->mv[dir][n][0] = s->current_picture.f.motion_val[dir][xy + v->blocks_off][0] = ((px + dmv_x + r_x) & ((r_x << 1) - 1)) - r_x; - s->mv[dir][n][1] = s->current_picture.f.motion_val[dir][xy + v->blocks_off][1] = ((py + dmv_y + r_y - y_bias) & ((r_y << 1) - 1)) - r_y + y_bias; + s->mv[dir][n][0] = s->current_picture.motion_val[dir][xy + v->blocks_off][0] = ((px + dmv_x + r_x) & ((r_x << 1) - 1)) - r_x; + s->mv[dir][n][1] = s->current_picture.motion_val[dir][xy + v->blocks_off][1] = ((py + dmv_y + r_y - y_bias) & ((r_y << 1) - 1)) - r_y + y_bias; if (mv1) { /* duplicate motion data for 1-MV block */ - s->current_picture.f.motion_val[dir][xy + 1 + v->blocks_off][0] = s->current_picture.f.motion_val[dir][xy + v->blocks_off][0]; - s->current_picture.f.motion_val[dir][xy + 1 + v->blocks_off][1] = s->current_picture.f.motion_val[dir][xy + v->blocks_off][1]; - s->current_picture.f.motion_val[dir][xy + wrap + v->blocks_off][0] = s->current_picture.f.motion_val[dir][xy + v->blocks_off][0]; - s->current_picture.f.motion_val[dir][xy + wrap + v->blocks_off][1] = s->current_picture.f.motion_val[dir][xy + v->blocks_off][1]; - s->current_picture.f.motion_val[dir][xy + wrap + 1 + v->blocks_off][0] = s->current_picture.f.motion_val[dir][xy + v->blocks_off][0]; - s->current_picture.f.motion_val[dir][xy + wrap + 1 + v->blocks_off][1] = s->current_picture.f.motion_val[dir][xy + v->blocks_off][1]; + s->current_picture.motion_val[dir][xy + 1 + v->blocks_off][0] = s->current_picture.motion_val[dir][xy + v->blocks_off][0]; + s->current_picture.motion_val[dir][xy + 1 + v->blocks_off][1] = s->current_picture.motion_val[dir][xy + v->blocks_off][1]; + s->current_picture.motion_val[dir][xy + wrap + v->blocks_off][0] = s->current_picture.motion_val[dir][xy + v->blocks_off][0]; + s->current_picture.motion_val[dir][xy + wrap + v->blocks_off][1] = s->current_picture.motion_val[dir][xy + v->blocks_off][1]; + s->current_picture.motion_val[dir][xy + wrap + 1 + v->blocks_off][0] = s->current_picture.motion_val[dir][xy + v->blocks_off][0]; + s->current_picture.motion_val[dir][xy + wrap + 1 + v->blocks_off][1] = s->current_picture.motion_val[dir][xy + v->blocks_off][1]; v->mv_f[dir][xy + 1 + v->blocks_off] = v->mv_f[dir][xy + v->blocks_off]; v->mv_f[dir][xy + wrap + v->blocks_off] = v->mv_f[dir][xy + wrap + 1 + v->blocks_off] = v->mv_f[dir][xy + v->blocks_off]; } @@ -1616,24 +1616,24 @@ static inline void vc1_pred_mv_intfr(VC1Context *v, int n, int dmv_x, int dmv_y, xy = s->block_index[n]; if (s->mb_intra) { - s->mv[0][n][0] = s->current_picture.f.motion_val[0][xy][0] = 0; - s->mv[0][n][1] = s->current_picture.f.motion_val[0][xy][1] = 0; - s->current_picture.f.motion_val[1][xy][0] = 0; - s->current_picture.f.motion_val[1][xy][1] = 0; + s->mv[0][n][0] = s->current_picture.motion_val[0][xy][0] = 0; + s->mv[0][n][1] = s->current_picture.motion_val[0][xy][1] = 0; + s->current_picture.motion_val[1][xy][0] = 0; + s->current_picture.motion_val[1][xy][1] = 0; if (mvn == 1) { /* duplicate motion data for 1-MV block */ - s->current_picture.f.motion_val[0][xy + 1][0] = 0; - s->current_picture.f.motion_val[0][xy + 1][1] = 0; - s->current_picture.f.motion_val[0][xy + wrap][0] = 0; - s->current_picture.f.motion_val[0][xy + wrap][1] = 0; - s->current_picture.f.motion_val[0][xy + wrap + 1][0] = 0; - s->current_picture.f.motion_val[0][xy + wrap + 1][1] = 0; + s->current_picture.motion_val[0][xy + 1][0] = 0; + s->current_picture.motion_val[0][xy + 1][1] = 0; + s->current_picture.motion_val[0][xy + wrap][0] = 0; + s->current_picture.motion_val[0][xy + wrap][1] = 0; + s->current_picture.motion_val[0][xy + wrap + 1][0] = 0; + s->current_picture.motion_val[0][xy + wrap + 1][1] = 0; v->luma_mv[s->mb_x][0] = v->luma_mv[s->mb_x][1] = 0; - s->current_picture.f.motion_val[1][xy + 1][0] = 0; - s->current_picture.f.motion_val[1][xy + 1][1] = 0; - s->current_picture.f.motion_val[1][xy + wrap][0] = 0; - s->current_picture.f.motion_val[1][xy + wrap][1] = 0; - s->current_picture.f.motion_val[1][xy + wrap + 1][0] = 0; - s->current_picture.f.motion_val[1][xy + wrap + 1][1] = 0; + s->current_picture.motion_val[1][xy + 1][0] = 0; + s->current_picture.motion_val[1][xy + 1][1] = 0; + s->current_picture.motion_val[1][xy + wrap][0] = 0; + s->current_picture.motion_val[1][xy + wrap][1] = 0; + s->current_picture.motion_val[1][xy + wrap + 1][0] = 0; + s->current_picture.motion_val[1][xy + wrap + 1][1] = 0; } return; } @@ -1643,14 +1643,14 @@ static inline void vc1_pred_mv_intfr(VC1Context *v, int n, int dmv_x, int dmv_y, if (s->mb_x || (n == 1) || (n == 3)) { if ((v->blk_mv_type[xy]) // current block (MB) has a field MV || (!v->blk_mv_type[xy] && !v->blk_mv_type[xy - 1])) { // or both have frame MV - A[0] = s->current_picture.f.motion_val[0][xy - 1][0]; - A[1] = s->current_picture.f.motion_val[0][xy - 1][1]; + A[0] = s->current_picture.motion_val[0][xy - 1][0]; + A[1] = s->current_picture.motion_val[0][xy - 1][1]; a_valid = 1; } else { // current block has frame mv and cand. has field MV (so average) - A[0] = (s->current_picture.f.motion_val[0][xy - 1][0] - + s->current_picture.f.motion_val[0][xy - 1 + off * wrap][0] + 1) >> 1; - A[1] = (s->current_picture.f.motion_val[0][xy - 1][1] - + s->current_picture.f.motion_val[0][xy - 1 + off * wrap][1] + 1) >> 1; + A[0] = (s->current_picture.motion_val[0][xy - 1][0] + + s->current_picture.motion_val[0][xy - 1 + off * wrap][0] + 1) >> 1; + A[1] = (s->current_picture.motion_val[0][xy - 1][1] + + s->current_picture.motion_val[0][xy - 1 + off * wrap][1] + 1) >> 1; a_valid = 1; } if (!(n & 1) && v->is_intra[s->mb_x - 1]) { @@ -1670,11 +1670,11 @@ static inline void vc1_pred_mv_intfr(VC1Context *v, int n, int dmv_x, int dmv_y, if (v->blk_mv_type[pos_b] && v->blk_mv_type[xy]) { n_adj = (n & 2) | (n & 1); } - B[0] = s->current_picture.f.motion_val[0][s->block_index[n_adj] - 2 * wrap][0]; - B[1] = s->current_picture.f.motion_val[0][s->block_index[n_adj] - 2 * wrap][1]; + B[0] = s->current_picture.motion_val[0][s->block_index[n_adj] - 2 * wrap][0]; + B[1] = s->current_picture.motion_val[0][s->block_index[n_adj] - 2 * wrap][1]; if (v->blk_mv_type[pos_b] && !v->blk_mv_type[xy]) { - B[0] = (B[0] + s->current_picture.f.motion_val[0][s->block_index[n_adj ^ 2] - 2 * wrap][0] + 1) >> 1; - B[1] = (B[1] + s->current_picture.f.motion_val[0][s->block_index[n_adj ^ 2] - 2 * wrap][1] + 1) >> 1; + B[0] = (B[0] + s->current_picture.motion_val[0][s->block_index[n_adj ^ 2] - 2 * wrap][0] + 1) >> 1; + B[1] = (B[1] + s->current_picture.motion_val[0][s->block_index[n_adj ^ 2] - 2 * wrap][1] + 1) >> 1; } } if (s->mb_width > 1) { @@ -1685,11 +1685,11 @@ static inline void vc1_pred_mv_intfr(VC1Context *v, int n, int dmv_x, int dmv_y, if (v->blk_mv_type[pos_c] && v->blk_mv_type[xy]) { n_adj = n & 2; } - C[0] = s->current_picture.f.motion_val[0][s->block_index[n_adj] - 2 * wrap + 2][0]; - C[1] = s->current_picture.f.motion_val[0][s->block_index[n_adj] - 2 * wrap + 2][1]; + C[0] = s->current_picture.motion_val[0][s->block_index[n_adj] - 2 * wrap + 2][0]; + C[1] = s->current_picture.motion_val[0][s->block_index[n_adj] - 2 * wrap + 2][1]; if (v->blk_mv_type[pos_c] && !v->blk_mv_type[xy]) { - C[0] = (1 + C[0] + (s->current_picture.f.motion_val[0][s->block_index[n_adj ^ 2] - 2 * wrap + 2][0])) >> 1; - C[1] = (1 + C[1] + (s->current_picture.f.motion_val[0][s->block_index[n_adj ^ 2] - 2 * wrap + 2][1])) >> 1; + C[0] = (1 + C[0] + (s->current_picture.motion_val[0][s->block_index[n_adj ^ 2] - 2 * wrap + 2][0])) >> 1; + C[1] = (1 + C[1] + (s->current_picture.motion_val[0][s->block_index[n_adj ^ 2] - 2 * wrap + 2][1])) >> 1; } if (s->mb_x == s->mb_width - 1) { if (!v->is_intra[s->mb_x - s->mb_stride - 1]) { @@ -1699,11 +1699,11 @@ static inline void vc1_pred_mv_intfr(VC1Context *v, int n, int dmv_x, int dmv_y, if (v->blk_mv_type[pos_c] && v->blk_mv_type[xy]) { n_adj = n | 1; } - C[0] = s->current_picture.f.motion_val[0][s->block_index[n_adj] - 2 * wrap - 2][0]; - C[1] = s->current_picture.f.motion_val[0][s->block_index[n_adj] - 2 * wrap - 2][1]; + C[0] = s->current_picture.motion_val[0][s->block_index[n_adj] - 2 * wrap - 2][0]; + C[1] = s->current_picture.motion_val[0][s->block_index[n_adj] - 2 * wrap - 2][1]; if (v->blk_mv_type[pos_c] && !v->blk_mv_type[xy]) { - C[0] = (1 + C[0] + s->current_picture.f.motion_val[0][s->block_index[1] - 2 * wrap - 2][0]) >> 1; - C[1] = (1 + C[1] + s->current_picture.f.motion_val[0][s->block_index[1] - 2 * wrap - 2][1]) >> 1; + C[0] = (1 + C[0] + s->current_picture.motion_val[0][s->block_index[1] - 2 * wrap - 2][0]) >> 1; + C[1] = (1 + C[1] + s->current_picture.motion_val[0][s->block_index[1] - 2 * wrap - 2][1]) >> 1; } } else c_valid = 0; @@ -1714,12 +1714,12 @@ static inline void vc1_pred_mv_intfr(VC1Context *v, int n, int dmv_x, int dmv_y, } else { pos_b = s->block_index[1]; b_valid = 1; - B[0] = s->current_picture.f.motion_val[0][pos_b][0]; - B[1] = s->current_picture.f.motion_val[0][pos_b][1]; + B[0] = s->current_picture.motion_val[0][pos_b][0]; + B[1] = s->current_picture.motion_val[0][pos_b][1]; pos_c = s->block_index[0]; c_valid = 1; - C[0] = s->current_picture.f.motion_val[0][pos_c][0]; - C[1] = s->current_picture.f.motion_val[0][pos_c][1]; + C[0] = s->current_picture.motion_val[0][pos_c][0]; + C[1] = s->current_picture.motion_val[0][pos_c][1]; } total_valid = a_valid + b_valid + c_valid; @@ -1807,18 +1807,18 @@ static inline void vc1_pred_mv_intfr(VC1Context *v, int n, int dmv_x, int dmv_y, } /* store MV using signed modulus of MV range defined in 4.11 */ - s->mv[0][n][0] = s->current_picture.f.motion_val[0][xy][0] = ((px + dmv_x + r_x) & ((r_x << 1) - 1)) - r_x; - s->mv[0][n][1] = s->current_picture.f.motion_val[0][xy][1] = ((py + dmv_y + r_y) & ((r_y << 1) - 1)) - r_y; + s->mv[0][n][0] = s->current_picture.motion_val[0][xy][0] = ((px + dmv_x + r_x) & ((r_x << 1) - 1)) - r_x; + s->mv[0][n][1] = s->current_picture.motion_val[0][xy][1] = ((py + dmv_y + r_y) & ((r_y << 1) - 1)) - r_y; if (mvn == 1) { /* duplicate motion data for 1-MV block */ - s->current_picture.f.motion_val[0][xy + 1 ][0] = s->current_picture.f.motion_val[0][xy][0]; - s->current_picture.f.motion_val[0][xy + 1 ][1] = s->current_picture.f.motion_val[0][xy][1]; - s->current_picture.f.motion_val[0][xy + wrap ][0] = s->current_picture.f.motion_val[0][xy][0]; - s->current_picture.f.motion_val[0][xy + wrap ][1] = s->current_picture.f.motion_val[0][xy][1]; - s->current_picture.f.motion_val[0][xy + wrap + 1][0] = s->current_picture.f.motion_val[0][xy][0]; - s->current_picture.f.motion_val[0][xy + wrap + 1][1] = s->current_picture.f.motion_val[0][xy][1]; + s->current_picture.motion_val[0][xy + 1 ][0] = s->current_picture.motion_val[0][xy][0]; + s->current_picture.motion_val[0][xy + 1 ][1] = s->current_picture.motion_val[0][xy][1]; + s->current_picture.motion_val[0][xy + wrap ][0] = s->current_picture.motion_val[0][xy][0]; + s->current_picture.motion_val[0][xy + wrap ][1] = s->current_picture.motion_val[0][xy][1]; + s->current_picture.motion_val[0][xy + wrap + 1][0] = s->current_picture.motion_val[0][xy][0]; + s->current_picture.motion_val[0][xy + wrap + 1][1] = s->current_picture.motion_val[0][xy][1]; } else if (mvn == 2) { /* duplicate motion data for 2-Field MV block */ - s->current_picture.f.motion_val[0][xy + 1][0] = s->current_picture.f.motion_val[0][xy][0]; - s->current_picture.f.motion_val[0][xy + 1][1] = s->current_picture.f.motion_val[0][xy][1]; + s->current_picture.motion_val[0][xy + 1][0] = s->current_picture.motion_val[0][xy][0]; + s->current_picture.motion_val[0][xy + 1][1] = s->current_picture.motion_val[0][xy][1]; s->mv[0][n + 1][0] = s->mv[0][n][0]; s->mv[0][n + 1][1] = s->mv[0][n][1]; } @@ -2041,17 +2041,17 @@ static inline void vc1_pred_b_mv(VC1Context *v, int dmv_x[2], int dmv_y[2], xy = s->block_index[0]; if (s->mb_intra) { - s->current_picture.f.motion_val[0][xy + v->blocks_off][0] = - s->current_picture.f.motion_val[0][xy + v->blocks_off][1] = - s->current_picture.f.motion_val[1][xy + v->blocks_off][0] = - s->current_picture.f.motion_val[1][xy + v->blocks_off][1] = 0; + s->current_picture.motion_val[0][xy + v->blocks_off][0] = + s->current_picture.motion_val[0][xy + v->blocks_off][1] = + s->current_picture.motion_val[1][xy + v->blocks_off][0] = + s->current_picture.motion_val[1][xy + v->blocks_off][1] = 0; return; } if (!v->field_mode) { - s->mv[0][0][0] = scale_mv(s->next_picture.f.motion_val[1][xy][0], v->bfraction, 0, s->quarter_sample); - s->mv[0][0][1] = scale_mv(s->next_picture.f.motion_val[1][xy][1], v->bfraction, 0, s->quarter_sample); - s->mv[1][0][0] = scale_mv(s->next_picture.f.motion_val[1][xy][0], v->bfraction, 1, s->quarter_sample); - s->mv[1][0][1] = scale_mv(s->next_picture.f.motion_val[1][xy][1], v->bfraction, 1, s->quarter_sample); + s->mv[0][0][0] = scale_mv(s->next_picture.motion_val[1][xy][0], v->bfraction, 0, s->quarter_sample); + s->mv[0][0][1] = scale_mv(s->next_picture.motion_val[1][xy][1], v->bfraction, 0, s->quarter_sample); + s->mv[1][0][0] = scale_mv(s->next_picture.motion_val[1][xy][0], v->bfraction, 1, s->quarter_sample); + s->mv[1][0][1] = scale_mv(s->next_picture.motion_val[1][xy][1], v->bfraction, 1, s->quarter_sample); /* Pullback predicted motion vectors as specified in 8.4.5.4 */ s->mv[0][0][0] = av_clip(s->mv[0][0][0], -60 - (s->mb_x << 6), (s->mb_width << 6) - 4 - (s->mb_x << 6)); @@ -2060,18 +2060,18 @@ static inline void vc1_pred_b_mv(VC1Context *v, int dmv_x[2], int dmv_y[2], s->mv[1][0][1] = av_clip(s->mv[1][0][1], -60 - (s->mb_y << 6), (s->mb_height << 6) - 4 - (s->mb_y << 6)); } if (direct) { - s->current_picture.f.motion_val[0][xy + v->blocks_off][0] = s->mv[0][0][0]; - s->current_picture.f.motion_val[0][xy + v->blocks_off][1] = s->mv[0][0][1]; - s->current_picture.f.motion_val[1][xy + v->blocks_off][0] = s->mv[1][0][0]; - s->current_picture.f.motion_val[1][xy + v->blocks_off][1] = s->mv[1][0][1]; + s->current_picture.motion_val[0][xy + v->blocks_off][0] = s->mv[0][0][0]; + s->current_picture.motion_val[0][xy + v->blocks_off][1] = s->mv[0][0][1]; + s->current_picture.motion_val[1][xy + v->blocks_off][0] = s->mv[1][0][0]; + s->current_picture.motion_val[1][xy + v->blocks_off][1] = s->mv[1][0][1]; return; } if ((mvtype == BMV_TYPE_FORWARD) || (mvtype == BMV_TYPE_INTERPOLATED)) { - C = s->current_picture.f.motion_val[0][xy - 2]; - A = s->current_picture.f.motion_val[0][xy - wrap * 2]; + C = s->current_picture.motion_val[0][xy - 2]; + A = s->current_picture.motion_val[0][xy - wrap * 2]; off = (s->mb_x == (s->mb_width - 1)) ? -2 : 2; - B = s->current_picture.f.motion_val[0][xy - wrap * 2 + off]; + B = s->current_picture.motion_val[0][xy - wrap * 2 + off]; if (!s->mb_x) C[0] = C[1] = 0; if (!s->first_slice_line) { // predictor A is not out of bounds @@ -2146,10 +2146,10 @@ static inline void vc1_pred_b_mv(VC1Context *v, int dmv_x[2], int dmv_y[2], s->mv[0][0][1] = ((py + dmv_y[0] + r_y) & ((r_y << 1) - 1)) - r_y; } if ((mvtype == BMV_TYPE_BACKWARD) || (mvtype == BMV_TYPE_INTERPOLATED)) { - C = s->current_picture.f.motion_val[1][xy - 2]; - A = s->current_picture.f.motion_val[1][xy - wrap * 2]; + C = s->current_picture.motion_val[1][xy - 2]; + A = s->current_picture.motion_val[1][xy - wrap * 2]; off = (s->mb_x == (s->mb_width - 1)) ? -2 : 2; - B = s->current_picture.f.motion_val[1][xy - wrap * 2 + off]; + B = s->current_picture.motion_val[1][xy - wrap * 2 + off]; if (!s->mb_x) C[0] = C[1] = 0; @@ -2225,10 +2225,10 @@ static inline void vc1_pred_b_mv(VC1Context *v, int dmv_x[2], int dmv_y[2], s->mv[1][0][0] = ((px + dmv_x[1] + r_x) & ((r_x << 1) - 1)) - r_x; s->mv[1][0][1] = ((py + dmv_y[1] + r_y) & ((r_y << 1) - 1)) - r_y; } - s->current_picture.f.motion_val[0][xy][0] = s->mv[0][0][0]; - s->current_picture.f.motion_val[0][xy][1] = s->mv[0][0][1]; - s->current_picture.f.motion_val[1][xy][0] = s->mv[1][0][0]; - s->current_picture.f.motion_val[1][xy][1] = s->mv[1][0][1]; + s->current_picture.motion_val[0][xy][0] = s->mv[0][0][0]; + s->current_picture.motion_val[0][xy][1] = s->mv[0][0][1]; + s->current_picture.motion_val[1][xy][0] = s->mv[1][0][0]; + s->current_picture.motion_val[1][xy][1] = s->mv[1][0][1]; } static inline void vc1_pred_b_mv_intfi(VC1Context *v, int n, int *dmv_x, int *dmv_y, int mv1, int *pred_flag) @@ -2239,14 +2239,14 @@ static inline void vc1_pred_b_mv_intfi(VC1Context *v, int n, int *dmv_x, int *dm if (v->bmvtype == BMV_TYPE_DIRECT) { int total_opp, k, f; - if (s->next_picture.f.mb_type[mb_pos + v->mb_off] != MB_TYPE_INTRA) { - s->mv[0][0][0] = scale_mv(s->next_picture.f.motion_val[1][s->block_index[0] + v->blocks_off][0], + if (s->next_picture.mb_type[mb_pos + v->mb_off] != MB_TYPE_INTRA) { + s->mv[0][0][0] = scale_mv(s->next_picture.motion_val[1][s->block_index[0] + v->blocks_off][0], v->bfraction, 0, s->quarter_sample); - s->mv[0][0][1] = scale_mv(s->next_picture.f.motion_val[1][s->block_index[0] + v->blocks_off][1], + s->mv[0][0][1] = scale_mv(s->next_picture.motion_val[1][s->block_index[0] + v->blocks_off][1], v->bfraction, 0, s->quarter_sample); - s->mv[1][0][0] = scale_mv(s->next_picture.f.motion_val[1][s->block_index[0] + v->blocks_off][0], + s->mv[1][0][0] = scale_mv(s->next_picture.motion_val[1][s->block_index[0] + v->blocks_off][0], v->bfraction, 1, s->quarter_sample); - s->mv[1][0][1] = scale_mv(s->next_picture.f.motion_val[1][s->block_index[0] + v->blocks_off][1], + s->mv[1][0][1] = scale_mv(s->next_picture.motion_val[1][s->block_index[0] + v->blocks_off][1], v->bfraction, 1, s->quarter_sample); total_opp = v->mv_f_next[0][s->block_index[0] + v->blocks_off] @@ -2261,10 +2261,10 @@ static inline void vc1_pred_b_mv_intfi(VC1Context *v, int n, int *dmv_x, int *dm } v->ref_field_type[0] = v->ref_field_type[1] = v->cur_field_type ^ f; for (k = 0; k < 4; k++) { - s->current_picture.f.motion_val[0][s->block_index[k] + v->blocks_off][0] = s->mv[0][0][0]; - s->current_picture.f.motion_val[0][s->block_index[k] + v->blocks_off][1] = s->mv[0][0][1]; - s->current_picture.f.motion_val[1][s->block_index[k] + v->blocks_off][0] = s->mv[1][0][0]; - s->current_picture.f.motion_val[1][s->block_index[k] + v->blocks_off][1] = s->mv[1][0][1]; + s->current_picture.motion_val[0][s->block_index[k] + v->blocks_off][0] = s->mv[0][0][0]; + s->current_picture.motion_val[0][s->block_index[k] + v->blocks_off][1] = s->mv[0][0][1]; + s->current_picture.motion_val[1][s->block_index[k] + v->blocks_off][0] = s->mv[1][0][0]; + s->current_picture.motion_val[1][s->block_index[k] + v->blocks_off][1] = s->mv[1][0][1]; v->mv_f[0][s->block_index[k] + v->blocks_off] = f; v->mv_f[1][s->block_index[k] + v->blocks_off] = f; } @@ -2382,17 +2382,17 @@ static inline int vc1_pred_dc(MpegEncContext *s, int overlap, int pq, int n, b = dc_val[ - 1 - wrap]; a = dc_val[ - wrap]; /* scale predictors if needed */ - q1 = s->current_picture.f.qscale_table[mb_pos]; + q1 = s->current_picture.qscale_table[mb_pos]; dqscale_index = s->y_dc_scale_table[q1] - 1; if (dqscale_index < 0) return 0; if (c_avail && (n != 1 && n != 3)) { - q2 = s->current_picture.f.qscale_table[mb_pos - 1]; + q2 = s->current_picture.qscale_table[mb_pos - 1]; if (q2 && q2 != q1) c = (c * s->y_dc_scale_table[q2] * ff_vc1_dqscale[dqscale_index] + 0x20000) >> 18; } if (a_avail && (n != 2 && n != 3)) { - q2 = s->current_picture.f.qscale_table[mb_pos - s->mb_stride]; + q2 = s->current_picture.qscale_table[mb_pos - s->mb_stride]; if (q2 && q2 != q1) a = (a * s->y_dc_scale_table[q2] * ff_vc1_dqscale[dqscale_index] + 0x20000) >> 18; } @@ -2402,7 +2402,7 @@ static inline int vc1_pred_dc(MpegEncContext *s, int overlap, int pq, int n, off--; if (n != 2) off -= s->mb_stride; - q2 = s->current_picture.f.qscale_table[off]; + q2 = s->current_picture.qscale_table[off]; if (q2 && q2 != q1) b = (b * s->y_dc_scale_table[q2] * ff_vc1_dqscale[dqscale_index] + 0x20000) >> 18; } @@ -2773,11 +2773,11 @@ static int vc1_decode_i_block_adv(VC1Context *v, int16_t block[64], int n, else // top ac_val -= 16 * s->block_wrap[n]; - q1 = s->current_picture.f.qscale_table[mb_pos]; + q1 = s->current_picture.qscale_table[mb_pos]; if ( dc_pred_dir && c_avail && mb_pos) - q2 = s->current_picture.f.qscale_table[mb_pos - 1]; + q2 = s->current_picture.qscale_table[mb_pos - 1]; if (!dc_pred_dir && a_avail && mb_pos >= s->mb_stride) - q2 = s->current_picture.f.qscale_table[mb_pos - s->mb_stride]; + q2 = s->current_picture.qscale_table[mb_pos - s->mb_stride]; if ( dc_pred_dir && n == 1) q2 = q1; if (!dc_pred_dir && n == 2) @@ -2996,11 +2996,11 @@ static int vc1_decode_intra_block(VC1Context *v, int16_t block[64], int n, else //top ac_val -= 16 * s->block_wrap[n]; - q1 = s->current_picture.f.qscale_table[mb_pos]; + q1 = s->current_picture.qscale_table[mb_pos]; if (dc_pred_dir && c_avail && mb_pos) - q2 = s->current_picture.f.qscale_table[mb_pos - 1]; + q2 = s->current_picture.qscale_table[mb_pos - 1]; if (!dc_pred_dir && a_avail && mb_pos >= s->mb_stride) - q2 = s->current_picture.f.qscale_table[mb_pos - s->mb_stride]; + q2 = s->current_picture.qscale_table[mb_pos - s->mb_stride]; if ( dc_pred_dir && n == 1) q2 = q1; if (!dc_pred_dir && n == 2) @@ -3318,7 +3318,7 @@ static av_always_inline void vc1_apply_p_v_loop_filter(VC1Context *v, int block_ bottom_is_intra = (block_num < 2) ? (mb_is_intra >> ((block_num + 2) * 4)) : (v->is_intra[s->mb_x] >> ((block_num - 2) * 4)); mv_stride = s->b8_stride; - mv = &s->current_picture.f.motion_val[0][s->block_index[block_num] - 2 * mv_stride]; + mv = &s->current_picture.motion_val[0][s->block_index[block_num] - 2 * mv_stride]; } if (bottom_is_intra & 1 || block_is_intra & 1 || @@ -3380,7 +3380,7 @@ static av_always_inline void vc1_apply_p_h_loop_filter(VC1Context *v, int block_ : (mb_cbp >> ((block_num + 1) * 4)); right_is_intra = (block_num & 1) ? (v->is_intra[s->mb_x - s->mb_stride] >> ((block_num - 1) * 4)) : (mb_is_intra >> ((block_num + 1) * 4)); - mv = &s->current_picture.f.motion_val[0][s->block_index[block_num] - s->b8_stride * 2 - 2]; + mv = &s->current_picture.motion_val[0][s->block_index[block_num] - s->b8_stride * 2 - 2]; } if (block_is_intra & 1 || right_is_intra & 1 || mv[0][0] != mv[1][0] || mv[0][1] != mv[1][1]) { v->vc1dsp.vc1_h_loop_filter8(dst, linesize, v->pq); @@ -3474,10 +3474,10 @@ static int vc1_decode_p_mb(VC1Context *v) GET_MVDATA(dmv_x, dmv_y); if (s->mb_intra) { - s->current_picture.f.motion_val[1][s->block_index[0]][0] = 0; - s->current_picture.f.motion_val[1][s->block_index[0]][1] = 0; + s->current_picture.motion_val[1][s->block_index[0]][0] = 0; + s->current_picture.motion_val[1][s->block_index[0]][1] = 0; } - s->current_picture.f.mb_type[mb_pos] = s->mb_intra ? MB_TYPE_INTRA : MB_TYPE_16x16; + s->current_picture.mb_type[mb_pos] = s->mb_intra ? MB_TYPE_INTRA : MB_TYPE_16x16; vc1_pred_mv(v, 0, dmv_x, dmv_y, 1, v->range_x, v->range_y, v->mb_type[0], 0, 0); /* FIXME Set DC val for inter block ? */ @@ -3494,7 +3494,7 @@ static int vc1_decode_p_mb(VC1Context *v) mquant = v->pq; cbp = 0; } - s->current_picture.f.qscale_table[mb_pos] = mquant; + s->current_picture.qscale_table[mb_pos] = mquant; if (!v->ttmbf && !s->mb_intra && mb_has_coeffs) ttmb = get_vlc2(gb, ff_vc1_ttmb_vlc[v->tt_index].table, @@ -3548,8 +3548,8 @@ static int vc1_decode_p_mb(VC1Context *v) v->mb_type[0][s->block_index[i]] = 0; s->dc_val[0][s->block_index[i]] = 0; } - s->current_picture.f.mb_type[mb_pos] = MB_TYPE_SKIP; - s->current_picture.f.qscale_table[mb_pos] = 0; + s->current_picture.mb_type[mb_pos] = MB_TYPE_SKIP; + s->current_picture.qscale_table[mb_pos] = 0; vc1_pred_mv(v, 0, 0, 0, 1, v->range_x, v->range_y, v->mb_type[0], 0, 0); vc1_mc_1mv(v, 0); } @@ -3592,7 +3592,7 @@ static int vc1_decode_p_mb(VC1Context *v) if (!intra_count && !coded_inter) goto end; GET_MQUANT(); - s->current_picture.f.qscale_table[mb_pos] = mquant; + s->current_picture.qscale_table[mb_pos] = mquant; /* test if block is intra and has pred */ { int intrapred = 0; @@ -3655,7 +3655,7 @@ static int vc1_decode_p_mb(VC1Context *v) } } else { // skipped MB s->mb_intra = 0; - s->current_picture.f.qscale_table[mb_pos] = 0; + s->current_picture.qscale_table[mb_pos] = 0; for (i = 0; i < 6; i++) { v->mb_type[0][s->block_index[i]] = 0; s->dc_val[0][s->block_index[i]] = 0; @@ -3665,7 +3665,7 @@ static int vc1_decode_p_mb(VC1Context *v) vc1_mc_4mv_luma(v, i, 0); } vc1_mc_4mv_chroma(v, 0); - s->current_picture.f.qscale_table[mb_pos] = 0; + s->current_picture.qscale_table[mb_pos] = 0; } } end: @@ -3740,9 +3740,9 @@ static int vc1_decode_p_mb_intfr(VC1Context *v) break; } if (ff_vc1_mbmode_intfrp[v->fourmvswitch][idx_mbmode][0] == MV_PMODE_INTFR_INTRA) { // intra MB - s->current_picture.f.motion_val[1][s->block_index[0]][0] = 0; - s->current_picture.f.motion_val[1][s->block_index[0]][1] = 0; - s->current_picture.f.mb_type[mb_pos] = MB_TYPE_INTRA; + s->current_picture.motion_val[1][s->block_index[0]][0] = 0; + s->current_picture.motion_val[1][s->block_index[0]][1] = 0; + s->current_picture.mb_type[mb_pos] = MB_TYPE_INTRA; s->mb_intra = v->is_intra[s->mb_x] = 1; for (i = 0; i < 6; i++) v->mb_type[0][s->block_index[i]] = 1; @@ -3752,7 +3752,7 @@ static int vc1_decode_p_mb_intfr(VC1Context *v) cbp = 1 + get_vlc2(&v->s.gb, v->cbpcy_vlc->table, VC1_CBPCY_P_VLC_BITS, 2); v->s.ac_pred = v->acpred_plane[mb_pos] = get_bits1(gb); GET_MQUANT(); - s->current_picture.f.qscale_table[mb_pos] = mquant; + s->current_picture.qscale_table[mb_pos] = mquant; /* Set DC scale - y and c use the same (not sure if necessary here) */ s->y_dc_scale = s->y_dc_scale_table[mquant]; s->c_dc_scale = s->c_dc_scale_table[mquant]; @@ -3844,7 +3844,7 @@ static int vc1_decode_p_mb_intfr(VC1Context *v) } if (cbp) GET_MQUANT(); // p. 227 - s->current_picture.f.qscale_table[mb_pos] = mquant; + s->current_picture.qscale_table[mb_pos] = mquant; if (!v->ttmbf && cbp) ttmb = get_vlc2(gb, ff_vc1_ttmb_vlc[v->tt_index].table, VC1_TTMB_VLC_BITS, 2); for (i = 0; i < 6; i++) { @@ -3873,8 +3873,8 @@ static int vc1_decode_p_mb_intfr(VC1Context *v) v->mb_type[0][s->block_index[i]] = 0; s->dc_val[0][s->block_index[i]] = 0; } - s->current_picture.f.mb_type[mb_pos] = MB_TYPE_SKIP; - s->current_picture.f.qscale_table[mb_pos] = 0; + s->current_picture.mb_type[mb_pos] = MB_TYPE_SKIP; + s->current_picture.qscale_table[mb_pos] = 0; v->blk_mv_type[s->block_index[0]] = 0; v->blk_mv_type[s->block_index[1]] = 0; v->blk_mv_type[s->block_index[2]] = 0; @@ -3911,11 +3911,11 @@ static int vc1_decode_p_mb_intfi(VC1Context *v) idx_mbmode = get_vlc2(gb, v->mbmode_vlc->table, VC1_IF_MBMODE_VLC_BITS, 2); if (idx_mbmode <= 1) { // intra MB s->mb_intra = v->is_intra[s->mb_x] = 1; - s->current_picture.f.motion_val[1][s->block_index[0] + v->blocks_off][0] = 0; - s->current_picture.f.motion_val[1][s->block_index[0] + v->blocks_off][1] = 0; - s->current_picture.f.mb_type[mb_pos + v->mb_off] = MB_TYPE_INTRA; + s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][0] = 0; + s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][1] = 0; + s->current_picture.mb_type[mb_pos + v->mb_off] = MB_TYPE_INTRA; GET_MQUANT(); - s->current_picture.f.qscale_table[mb_pos] = mquant; + s->current_picture.qscale_table[mb_pos] = mquant; /* Set DC scale - y and c use the same (not sure if necessary here) */ s->y_dc_scale = s->y_dc_scale_table[mquant]; s->c_dc_scale = s->c_dc_scale_table[mquant]; @@ -3947,7 +3947,7 @@ static int vc1_decode_p_mb_intfi(VC1Context *v) } } else { s->mb_intra = v->is_intra[s->mb_x] = 0; - s->current_picture.f.mb_type[mb_pos + v->mb_off] = MB_TYPE_16x16; + s->current_picture.mb_type[mb_pos + v->mb_off] = MB_TYPE_16x16; for (i = 0; i < 6; i++) v->mb_type[0][s->block_index[i]] = 0; if (idx_mbmode <= 5) { // 1-MV dmv_x = dmv_y = pred_flag = 0; @@ -3978,7 +3978,7 @@ static int vc1_decode_p_mb_intfi(VC1Context *v) if (cbp) { GET_MQUANT(); } - s->current_picture.f.qscale_table[mb_pos] = mquant; + s->current_picture.qscale_table[mb_pos] = mquant; if (!v->ttmbf && cbp) { ttmb = get_vlc2(gb, ff_vc1_ttmb_vlc[v->tt_index].table, VC1_TTMB_VLC_BITS, 2); } @@ -4044,7 +4044,7 @@ static void vc1_decode_b_mb(VC1Context *v) v->mb_type[0][s->block_index[i]] = 0; s->dc_val[0][s->block_index[i]] = 0; } - s->current_picture.f.qscale_table[mb_pos] = 0; + s->current_picture.qscale_table[mb_pos] = 0; if (!direct) { if (!skipped) { @@ -4081,7 +4081,7 @@ static void vc1_decode_b_mb(VC1Context *v) cbp = get_vlc2(&v->s.gb, v->cbpcy_vlc->table, VC1_CBPCY_P_VLC_BITS, 2); GET_MQUANT(); s->mb_intra = 0; - s->current_picture.f.qscale_table[mb_pos] = mquant; + s->current_picture.qscale_table[mb_pos] = mquant; if (!v->ttmbf) ttmb = get_vlc2(gb, ff_vc1_ttmb_vlc[v->tt_index].table, VC1_TTMB_VLC_BITS, 2); dmv_x[0] = dmv_y[0] = dmv_x[1] = dmv_y[1] = 0; @@ -4096,7 +4096,7 @@ static void vc1_decode_b_mb(VC1Context *v) } if (s->mb_intra && !mb_has_coeffs) { GET_MQUANT(); - s->current_picture.f.qscale_table[mb_pos] = mquant; + s->current_picture.qscale_table[mb_pos] = mquant; s->ac_pred = get_bits1(gb); cbp = 0; vc1_pred_b_mv(v, dmv_x, dmv_y, direct, bmvtype); @@ -4118,7 +4118,7 @@ static void vc1_decode_b_mb(VC1Context *v) s->ac_pred = get_bits1(gb); cbp = get_vlc2(&v->s.gb, v->cbpcy_vlc->table, VC1_CBPCY_P_VLC_BITS, 2); GET_MQUANT(); - s->current_picture.f.qscale_table[mb_pos] = mquant; + s->current_picture.qscale_table[mb_pos] = mquant; if (!v->ttmbf && !s->mb_intra && mb_has_coeffs) ttmb = get_vlc2(gb, ff_vc1_ttmb_vlc[v->tt_index].table, VC1_TTMB_VLC_BITS, 2); } @@ -4185,11 +4185,11 @@ static void vc1_decode_b_mb_intfi(VC1Context *v) idx_mbmode = get_vlc2(gb, v->mbmode_vlc->table, VC1_IF_MBMODE_VLC_BITS, 2); if (idx_mbmode <= 1) { // intra MB s->mb_intra = v->is_intra[s->mb_x] = 1; - s->current_picture.f.motion_val[1][s->block_index[0]][0] = 0; - s->current_picture.f.motion_val[1][s->block_index[0]][1] = 0; - s->current_picture.f.mb_type[mb_pos + v->mb_off] = MB_TYPE_INTRA; + s->current_picture.motion_val[1][s->block_index[0]][0] = 0; + s->current_picture.motion_val[1][s->block_index[0]][1] = 0; + s->current_picture.mb_type[mb_pos + v->mb_off] = MB_TYPE_INTRA; GET_MQUANT(); - s->current_picture.f.qscale_table[mb_pos] = mquant; + s->current_picture.qscale_table[mb_pos] = mquant; /* Set DC scale - y and c use the same (not sure if necessary here) */ s->y_dc_scale = s->y_dc_scale_table[mquant]; s->c_dc_scale = s->c_dc_scale_table[mquant]; @@ -4224,7 +4224,7 @@ static void vc1_decode_b_mb_intfi(VC1Context *v) } } else { s->mb_intra = v->is_intra[s->mb_x] = 0; - s->current_picture.f.mb_type[mb_pos + v->mb_off] = MB_TYPE_16x16; + s->current_picture.mb_type[mb_pos + v->mb_off] = MB_TYPE_16x16; for (i = 0; i < 6; i++) v->mb_type[0][s->block_index[i]] = 0; if (v->fmb_is_raw) fwd = v->forward_mb_plane[mb_pos] = get_bits1(gb); @@ -4290,7 +4290,7 @@ static void vc1_decode_b_mb_intfi(VC1Context *v) if (cbp) { GET_MQUANT(); } - s->current_picture.f.qscale_table[mb_pos] = mquant; + s->current_picture.qscale_table[mb_pos] = mquant; if (!v->ttmbf && cbp) { ttmb = get_vlc2(gb, ff_vc1_ttmb_vlc[v->tt_index].table, VC1_TTMB_VLC_BITS, 2); } @@ -4372,10 +4372,10 @@ static void vc1_decode_i_blocks(VC1Context *v) dst[5] = s->dest[2]; s->dsp.clear_blocks(s->block[0]); mb_pos = s->mb_x + s->mb_y * s->mb_width; - s->current_picture.f.mb_type[mb_pos] = MB_TYPE_INTRA; - s->current_picture.f.qscale_table[mb_pos] = v->pq; - s->current_picture.f.motion_val[1][s->block_index[0]][0] = 0; - s->current_picture.f.motion_val[1][s->block_index[0]][1] = 0; + s->current_picture.mb_type[mb_pos] = MB_TYPE_INTRA; + s->current_picture.qscale_table[mb_pos] = v->pq; + s->current_picture.motion_val[1][s->block_index[0]][0] = 0; + s->current_picture.motion_val[1][s->block_index[0]][1] = 0; // do actual MB decoding and displaying cbp = get_vlc2(&v->s.gb, ff_msmp4_mb_i_vlc.table, MB_INTRA_VLC_BITS, 2); @@ -4512,9 +4512,9 @@ static void vc1_decode_i_blocks_adv(VC1Context *v) ff_update_block_index(s); s->dsp.clear_blocks(block[0]); mb_pos = s->mb_x + s->mb_y * s->mb_stride; - s->current_picture.f.mb_type[mb_pos + v->mb_off] = MB_TYPE_INTRA; - s->current_picture.f.motion_val[1][s->block_index[0] + v->blocks_off][0] = 0; - s->current_picture.f.motion_val[1][s->block_index[0] + v->blocks_off][1] = 0; + s->current_picture.mb_type[mb_pos + v->mb_off] = MB_TYPE_INTRA; + s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][0] = 0; + s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][1] = 0; // do actual MB decoding and displaying if (v->fieldtx_is_raw) @@ -4530,7 +4530,7 @@ static void vc1_decode_i_blocks_adv(VC1Context *v) GET_MQUANT(); - s->current_picture.f.qscale_table[mb_pos] = mquant; + s->current_picture.qscale_table[mb_pos] = mquant; /* Set DC scale - y and c use the same */ s->y_dc_scale = s->y_dc_scale_table[mquant]; s->c_dc_scale = s->c_dc_scale_table[mquant]; @@ -5024,12 +5024,8 @@ static int vc1_decode_sprites(VC1Context *v, GetBitContext* gb) v->two_sprites = 0; } - if (v->sprite_output_frame.data[0]) - avctx->release_buffer(avctx, &v->sprite_output_frame); - - v->sprite_output_frame.buffer_hints = FF_BUFFER_HINTS_VALID; - v->sprite_output_frame.reference = 0; - if (ff_get_buffer(avctx, &v->sprite_output_frame) < 0) { + av_frame_unref(&v->sprite_output_frame); + if (ff_get_buffer(avctx, &v->sprite_output_frame, 0) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return -1; } @@ -5279,9 +5275,8 @@ av_cold int ff_vc1_decode_end(AVCodecContext *avctx) VC1Context *v = avctx->priv_data; int i; - if ((avctx->codec_id == AV_CODEC_ID_WMV3IMAGE || avctx->codec_id == AV_CODEC_ID_VC1IMAGE) - && v->sprite_output_frame.data[0]) - avctx->release_buffer(avctx, &v->sprite_output_frame); + av_frame_unref(&v->sprite_output_frame); + for (i = 0; i < 4; i++) av_freep(&v->sr_rows[i >> 1][i & 1]); av_freep(&v->hrd_rate); @@ -5315,7 +5310,7 @@ static int vc1_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size, n_slices = 0, i; + int buf_size = avpkt->size, n_slices = 0, i, ret; VC1Context *v = avctx->priv_data; MpegEncContext *s = &v->s; AVFrame *pict = data; @@ -5332,7 +5327,8 @@ static int vc1_decode_frame(AVCodecContext *avctx, void *data, if (buf_size == 0 || (buf_size == 4 && AV_RB32(buf) == VC1_CODE_ENDOFSEQ)) { /* special case for last picture */ if (s->low_delay == 0 && s->next_picture_ptr) { - *pict = s->next_picture_ptr->f; + if ((ret = av_frame_ref(pict, &s->next_picture_ptr->f)) < 0) + return ret; s->next_picture_ptr = NULL; *got_frame = 1; @@ -5650,17 +5646,21 @@ image: if (vc1_decode_sprites(v, &s->gb)) goto err; #endif - *pict = v->sprite_output_frame; + if ((ret = av_frame_ref(pict, &v->sprite_output_frame)) < 0) + goto err; *got_frame = 1; } else { if (s->pict_type == AV_PICTURE_TYPE_B || s->low_delay) { - *pict = s->current_picture_ptr->f; + if ((ret = av_frame_ref(pict, &s->current_picture_ptr->f)) < 0) + goto err; + ff_print_debug_info(s, s->current_picture_ptr); } else if (s->last_picture_ptr != NULL) { - *pict = s->last_picture_ptr->f; + if ((ret = av_frame_ref(pict, &s->last_picture_ptr->f)) < 0) + goto err; + ff_print_debug_info(s, s->last_picture_ptr); } if (s->last_picture_ptr || s->low_delay) { *got_frame = 1; - ff_print_debug_info(s, pict); } } diff --git a/libavcodec/vcr1.c b/libavcodec/vcr1.c index 499b1c75c6..c4b817ead8 100644 --- a/libavcodec/vcr1.c +++ b/libavcodec/vcr1.c @@ -29,55 +29,28 @@ #include "libavutil/internal.h" typedef struct VCR1Context { - AVFrame picture; int delta[16]; int offset[4]; } VCR1Context; -static av_cold int vcr1_common_init(AVCodecContext *avctx) -{ - VCR1Context *const a = avctx->priv_data; - - avctx->coded_frame = &a->picture; - - return 0; -} - static av_cold int vcr1_decode_init(AVCodecContext *avctx) { - vcr1_common_init(avctx); - avctx->pix_fmt = AV_PIX_FMT_YUV410P; return 0; } -static av_cold int vcr1_decode_end(AVCodecContext *avctx) -{ - VCR1Context *s = avctx->priv_data; - - if (s->picture.data[0]) - avctx->release_buffer(avctx, &s->picture); - - return 0; -} - static int vcr1_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; VCR1Context *const a = avctx->priv_data; - AVFrame *picture = data; - AVFrame *const p = &a->picture; + AVFrame *const p = data; const uint8_t *bytestream = buf; int i, x, y, ret; - if (p->data[0]) - avctx->release_buffer(avctx, p); - - p->reference = 0; - if ((ret = ff_get_buffer(avctx, p)) < 0) { + if ((ret = ff_get_buffer(avctx, p, 0)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } @@ -91,11 +64,11 @@ static int vcr1_decode_frame(AVCodecContext *avctx, void *data, for (y = 0; y < avctx->height; y++) { int offset; - uint8_t *luma = &a->picture.data[0][y * a->picture.linesize[0]]; + uint8_t *luma = &p->data[0][y * p->linesize[0]]; if ((y & 3) == 0) { - uint8_t *cb = &a->picture.data[1][(y >> 2) * a->picture.linesize[1]]; - uint8_t *cr = &a->picture.data[2][(y >> 2) * a->picture.linesize[2]]; + uint8_t *cb = &p->data[1][(y >> 2) * p->linesize[1]]; + uint8_t *cr = &p->data[2][(y >> 2) * p->linesize[2]]; for (i = 0; i < 4; i++) a->offset[i] = *bytestream++; @@ -131,7 +104,6 @@ static int vcr1_decode_frame(AVCodecContext *avctx, void *data, } } - *picture = a->picture; *got_frame = 1; return buf_size; @@ -143,7 +115,6 @@ AVCodec ff_vcr1_decoder = { .id = AV_CODEC_ID_VCR1, .priv_data_size = sizeof(VCR1Context), .init = vcr1_decode_init, - .close = vcr1_decode_end, .decode = vcr1_decode_frame, .capabilities = CODEC_CAP_DR1, .long_name = NULL_IF_CONFIG_SMALL("ATI VCR1"), diff --git a/libavcodec/vdpau.c b/libavcodec/vdpau.c index e5c459b414..66c7f59f27 100644 --- a/libavcodec/vdpau.c +++ b/libavcodec/vdpau.c @@ -104,7 +104,7 @@ void ff_vdpau_h264_set_reference_frames(H264Context *h) for (i = 0; i < ls; ++i) { pic = lp[i]; - if (!pic || !pic->f.reference) + if (!pic || !pic->reference) continue; pic_frame_idx = pic->long_ref ? pic->pic_id : pic->frame_num; @@ -122,8 +122,8 @@ void ff_vdpau_h264_set_reference_frames(H264Context *h) ++rf2; } if (rf2 != rf) { - rf2->top_is_reference |= (pic->f.reference & PICT_TOP_FIELD) ? VDP_TRUE : VDP_FALSE; - rf2->bottom_is_reference |= (pic->f.reference & PICT_BOTTOM_FIELD) ? VDP_TRUE : VDP_FALSE; + rf2->top_is_reference |= (pic->reference & PICT_TOP_FIELD) ? VDP_TRUE : VDP_FALSE; + rf2->bottom_is_reference |= (pic->reference & PICT_BOTTOM_FIELD) ? VDP_TRUE : VDP_FALSE; continue; } @@ -132,8 +132,8 @@ void ff_vdpau_h264_set_reference_frames(H264Context *h) rf->surface = render_ref->surface; rf->is_long_term = pic->long_ref; - rf->top_is_reference = (pic->f.reference & PICT_TOP_FIELD) ? VDP_TRUE : VDP_FALSE; - rf->bottom_is_reference = (pic->f.reference & PICT_BOTTOM_FIELD) ? VDP_TRUE : VDP_FALSE; + rf->top_is_reference = (pic->reference & PICT_TOP_FIELD) ? VDP_TRUE : VDP_FALSE; + rf->bottom_is_reference = (pic->reference & PICT_BOTTOM_FIELD) ? VDP_TRUE : VDP_FALSE; rf->field_order_cnt[0] = pic->field_poc[0]; rf->field_order_cnt[1] = pic->field_poc[1]; rf->frame_idx = pic_frame_idx; @@ -199,7 +199,7 @@ void ff_vdpau_h264_picture_complete(H264Context *h) if (render->info.h264.slice_count < 1) return; - render->info.h264.is_reference = (h->cur_pic_ptr->f.reference & 3) ? VDP_TRUE : VDP_FALSE; + render->info.h264.is_reference = (h->cur_pic_ptr->reference & 3) ? VDP_TRUE : VDP_FALSE; render->info.h264.field_pic_flag = h->picture_structure != PICT_FRAME; render->info.h264.bottom_field_flag = h->picture_structure == PICT_BOTTOM_FIELD; render->info.h264.num_ref_frames = h->sps.ref_frame_count; diff --git a/libavcodec/vdpau_h264.c b/libavcodec/vdpau_h264.c index 91f8008366..e787762e34 100644 --- a/libavcodec/vdpau_h264.c +++ b/libavcodec/vdpau_h264.c @@ -52,10 +52,10 @@ static void vdpau_h264_set_rf(VdpReferenceFrameH264 *rf, Picture *pic, VdpVideoSurface surface = ff_vdpau_get_surface_id(pic); if (pic_structure == 0) - pic_structure = pic->f.reference; + pic_structure = pic->reference; rf->surface = surface; - rf->is_long_term = pic->f.reference && pic->long_ref; + rf->is_long_term = pic->reference && pic->long_ref; rf->top_is_reference = (pic_structure & PICT_TOP_FIELD) != 0; rf->bottom_is_reference = (pic_structure & PICT_BOTTOM_FIELD) != 0; rf->field_order_cnt[0] = h264_foc(pic->field_poc[0]); @@ -83,7 +83,7 @@ static void vdpau_h264_set_reference_frames(AVCodecContext *avctx) VdpVideoSurface surface_ref; int pic_frame_idx; - if (!pic || !pic->f.reference) + if (!pic || !pic->reference) continue; pic_frame_idx = pic->long_ref ? pic->pic_id : pic->frame_num; surface_ref = ff_vdpau_get_surface_id(pic); @@ -97,15 +97,15 @@ static void vdpau_h264_set_reference_frames(AVCodecContext *avctx) ++rf2; } if (rf2 != rf) { - rf2->top_is_reference |= (pic->f.reference & PICT_TOP_FIELD) ? VDP_TRUE : VDP_FALSE; - rf2->bottom_is_reference |= (pic->f.reference & PICT_BOTTOM_FIELD) ? VDP_TRUE : VDP_FALSE; + rf2->top_is_reference |= (pic->reference & PICT_TOP_FIELD) ? VDP_TRUE : VDP_FALSE; + rf2->bottom_is_reference |= (pic->reference & PICT_BOTTOM_FIELD) ? VDP_TRUE : VDP_FALSE; continue; } if (rf >= &info->referenceFrames[H264_RF_COUNT]) continue; - vdpau_h264_set_rf(rf, pic, pic->f.reference); + vdpau_h264_set_rf(rf, pic, pic->reference); ++rf; } } diff --git a/libavcodec/version.h b/libavcodec/version.h index 78fcdbfaae..aaf8735686 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -103,5 +103,8 @@ #ifndef FF_API_DESTRUCT_PACKET #define FF_API_DESTRUCT_PACKET (LIBAVCODEC_VERSION_MAJOR < 56) #endif +#ifndef FF_API_GET_BUFFER +#define FF_API_GET_BUFFER (LIBAVCODEC_VERSION_MAJOR < 56) +#endif #endif /* AVCODEC_VERSION_H */ diff --git a/libavcodec/vmdav.c b/libavcodec/vmdav.c index 88cd167659..b5b5524919 100644 --- a/libavcodec/vmdav.c +++ b/libavcodec/vmdav.c @@ -59,7 +59,6 @@ typedef struct VmdVideoContext { AVCodecContext *avctx; - AVFrame frame; AVFrame prev_frame; const unsigned char *buf; @@ -207,7 +206,7 @@ static int rle_unpack(const unsigned char *src, unsigned char *dest, return ps - src; } -static void vmd_decode(VmdVideoContext *s) +static void vmd_decode(VmdVideoContext *s, AVFrame *frame) { int i; unsigned int *palette32; @@ -257,8 +256,8 @@ static void vmd_decode(VmdVideoContext *s) (frame_x || frame_y || (frame_width != s->avctx->width) || (frame_height != s->avctx->height))) { - memcpy(s->frame.data[0], s->prev_frame.data[0], - s->avctx->height * s->frame.linesize[0]); + memcpy(frame->data[0], s->prev_frame.data[0], + s->avctx->height * frame->linesize[0]); } /* check if there is a new palette */ @@ -288,7 +287,7 @@ static void vmd_decode(VmdVideoContext *s) pb_size = s->unpack_buffer_size; } - dp = &s->frame.data[0][frame_y * s->frame.linesize[0] + frame_x]; + dp = &frame->data[0][frame_y * frame->linesize[0] + frame_x]; pp = &s->prev_frame.data[0][frame_y * s->prev_frame.linesize[0] + frame_x]; switch (meth) { case 1: @@ -320,7 +319,7 @@ static void vmd_decode(VmdVideoContext *s) ofs, frame_width); break; } - dp += s->frame.linesize[0]; + dp += frame->linesize[0]; pp += s->prev_frame.linesize[0]; } break; @@ -332,7 +331,7 @@ static void vmd_decode(VmdVideoContext *s) memcpy(dp, pb, frame_width); pb += frame_width; pb_size -= frame_width; - dp += s->frame.linesize[0]; + dp += frame->linesize[0]; pp += s->prev_frame.linesize[0]; } break; @@ -371,7 +370,7 @@ static void vmd_decode(VmdVideoContext *s) av_log(s->avctx, AV_LOG_ERROR, "VMD video: offset > width (%d > %d)\n", ofs, frame_width); } - dp += s->frame.linesize[0]; + dp += frame->linesize[0]; pp += s->prev_frame.linesize[0]; } break; @@ -425,6 +424,8 @@ static int vmdvideo_decode_frame(AVCodecContext *avctx, const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; VmdVideoContext *s = avctx->priv_data; + AVFrame *frame = data; + int ret; s->buf = buf; s->size = buf_size; @@ -432,24 +433,22 @@ static int vmdvideo_decode_frame(AVCodecContext *avctx, if (buf_size < 16) return buf_size; - s->frame.reference = 1; - if (ff_get_buffer(avctx, &s->frame)) { + if ((ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF)) < 0) { av_log(s->avctx, AV_LOG_ERROR, "VMD Video: get_buffer() failed\n"); - return -1; + return ret; } - vmd_decode(s); + vmd_decode(s, frame); /* make the palette available on the way out */ - memcpy(s->frame.data[1], s->palette, PALETTE_COUNT * 4); + memcpy(frame->data[1], s->palette, PALETTE_COUNT * 4); /* shuffle frames */ - FFSWAP(AVFrame, s->frame, s->prev_frame); - if (s->frame.data[0]) - avctx->release_buffer(avctx, &s->frame); + av_frame_unref(&s->prev_frame); + if ((ret = av_frame_ref(&s->prev_frame, frame)) < 0) + return ret; *got_frame = 1; - *(AVFrame*)data = s->prev_frame; /* report that the buffer was completely consumed */ return buf_size; @@ -459,8 +458,7 @@ static av_cold int vmdvideo_decode_end(AVCodecContext *avctx) { VmdVideoContext *s = avctx->priv_data; - if (s->prev_frame.data[0]) - avctx->release_buffer(avctx, &s->prev_frame); + av_frame_unref(&s->prev_frame); av_free(s->unpack_buffer); return 0; @@ -607,7 +605,7 @@ static int vmdaudio_decode_frame(AVCodecContext *avctx, void *data, /* get output buffer */ frame->nb_samples = ((silent_chunks + audio_chunks) * avctx->block_align) / avctx->channels; - if ((ret = ff_get_buffer(avctx, frame)) < 0) { + if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } diff --git a/libavcodec/vmnc.c b/libavcodec/vmnc.c index 4071cdf51a..41e4730b44 100644 --- a/libavcodec/vmnc.c +++ b/libavcodec/vmnc.c @@ -31,6 +31,7 @@ #include "libavutil/common.h" #include "libavutil/intreadwrite.h" #include "avcodec.h" +#include "internal.h" enum EncTypes { MAGIC_WMVd = 0x574D5664, @@ -293,13 +294,11 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, VmncContext * const c = avctx->priv_data; uint8_t *outptr; const uint8_t *src = buf; - int dx, dy, w, h, depth, enc, chunks, res, size_left; + int dx, dy, w, h, depth, enc, chunks, res, size_left, ret; - c->pic.reference = 1; - c->pic.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE; - if(avctx->reget_buffer(avctx, &c->pic) < 0){ + if ((ret = ff_reget_buffer(avctx, &c->pic)) < 0) { av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); - return -1; + return ret; } c->pic.key_frame = 0; @@ -448,7 +447,8 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, } } *got_frame = 1; - *(AVFrame*)data = c->pic; + if ((ret = av_frame_ref(data, &c->pic)) < 0) + return ret; /* always report that the buffer was completely consumed */ return buf_size; @@ -502,8 +502,7 @@ static av_cold int decode_end(AVCodecContext *avctx) { VmncContext * const c = avctx->priv_data; - if (c->pic.data[0]) - avctx->release_buffer(avctx, &c->pic); + av_frame_unref(&c->pic); av_free(c->curbits); av_free(c->curmask); diff --git a/libavcodec/vorbisdec.c b/libavcodec/vorbisdec.c index c31dd17b8b..ebe7aa79dc 100644 --- a/libavcodec/vorbisdec.c +++ b/libavcodec/vorbisdec.c @@ -1684,7 +1684,7 @@ static int vorbis_decode_frame(AVCodecContext *avctx, void *data, /* get output buffer */ frame->nb_samples = vc->blocksize[1] / 2; - if ((ret = ff_get_buffer(avctx, frame)) < 0) { + if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } diff --git a/libavcodec/vp3.c b/libavcodec/vp3.c index f46ac32a9a..3d55c784aa 100644 --- a/libavcodec/vp3.c +++ b/libavcodec/vp3.c @@ -131,9 +131,9 @@ typedef struct Vp3DecodeContext { int version; int width, height; int chroma_x_shift, chroma_y_shift; - AVFrame golden_frame; - AVFrame last_frame; - AVFrame current_frame; + ThreadFrame golden_frame; + ThreadFrame last_frame; + ThreadFrame current_frame; int keyframe; DSPContext dsp; VideoDSPContext vdsp; @@ -261,19 +261,11 @@ static void vp3_decode_flush(AVCodecContext *avctx) { Vp3DecodeContext *s = avctx->priv_data; - if (s->golden_frame.data[0]) { - if (s->golden_frame.data[0] == s->last_frame.data[0]) - memset(&s->last_frame, 0, sizeof(AVFrame)); - if (s->current_frame.data[0] == s->golden_frame.data[0]) - memset(&s->current_frame, 0, sizeof(AVFrame)); + if (s->golden_frame.f) ff_thread_release_buffer(avctx, &s->golden_frame); - } - if (s->last_frame.data[0]) { - if (s->current_frame.data[0] == s->last_frame.data[0]) - memset(&s->current_frame, 0, sizeof(AVFrame)); + if (s->last_frame.f) ff_thread_release_buffer(avctx, &s->last_frame); - } - if (s->current_frame.data[0]) + if (s->current_frame.f) ff_thread_release_buffer(avctx, &s->current_frame); } @@ -292,6 +284,12 @@ static av_cold int vp3_decode_end(AVCodecContext *avctx) av_freep(&s->motion_val[1]); av_freep(&s->edge_emu_buffer); + /* release all frames */ + vp3_decode_flush(avctx); + av_frame_free(&s->current_frame.f); + av_frame_free(&s->last_frame.f); + av_frame_free(&s->golden_frame.f); + if (avctx->internal->is_copy) return 0; @@ -308,8 +306,6 @@ static av_cold int vp3_decode_end(AVCodecContext *avctx) ff_free_vlc(&s->mode_code_vlc); ff_free_vlc(&s->motion_vector_vlc); - /* release all frames */ - vp3_decode_flush(avctx); return 0; } @@ -1290,8 +1286,8 @@ static void apply_loop_filter(Vp3DecodeContext *s, int plane, int ystart, int ye int width = s->fragment_width[!!plane]; int height = s->fragment_height[!!plane]; int fragment = s->fragment_start [plane] + ystart * width; - int stride = s->current_frame.linesize[plane]; - uint8_t *plane_data = s->current_frame.data [plane]; + int stride = s->current_frame.f->linesize[plane]; + uint8_t *plane_data = s->current_frame.f->data [plane]; if (!s->flipped_image) stride = -stride; plane_data += s->data_offset[plane] + 8*ystart*stride; @@ -1420,14 +1416,14 @@ static void vp3_draw_horiz_band(Vp3DecodeContext *s, int y) } cy = y >> s->chroma_y_shift; - offset[0] = s->current_frame.linesize[0]*y; - offset[1] = s->current_frame.linesize[1]*cy; - offset[2] = s->current_frame.linesize[2]*cy; + offset[0] = s->current_frame.f->linesize[0]*y; + offset[1] = s->current_frame.f->linesize[1]*cy; + offset[2] = s->current_frame.f->linesize[2]*cy; for (i = 3; i < AV_NUM_DATA_POINTERS; i++) offset[i] = 0; emms_c(); - s->avctx->draw_horiz_band(s->avctx, &s->current_frame, offset, y, 3, h); + s->avctx->draw_horiz_band(s->avctx, s->current_frame.f, offset, y, 3, h); } /** @@ -1436,7 +1432,7 @@ static void vp3_draw_horiz_band(Vp3DecodeContext *s, int y) */ static void await_reference_row(Vp3DecodeContext *s, Vp3Fragment *fragment, int motion_y, int y) { - AVFrame *ref_frame; + ThreadFrame *ref_frame; int ref_row; int border = motion_y&1; @@ -1469,10 +1465,10 @@ static void render_slice(Vp3DecodeContext *s, int slice) return; for (plane = 0; plane < 3; plane++) { - uint8_t *output_plane = s->current_frame.data [plane] + s->data_offset[plane]; - uint8_t * last_plane = s-> last_frame.data [plane] + s->data_offset[plane]; - uint8_t *golden_plane = s-> golden_frame.data [plane] + s->data_offset[plane]; - int stride = s->current_frame.linesize[plane]; + uint8_t *output_plane = s->current_frame.f->data [plane] + s->data_offset[plane]; + uint8_t * last_plane = s-> last_frame.f->data [plane] + s->data_offset[plane]; + uint8_t *golden_plane = s-> golden_frame.f->data [plane] + s->data_offset[plane]; + int stride = s->current_frame.f->linesize[plane]; int plane_width = s->width >> (plane && s->chroma_x_shift); int plane_height = s->height >> (plane && s->chroma_y_shift); int8_t (*motion_val)[2] = s->motion_val[!!plane]; @@ -1657,14 +1653,36 @@ static av_cold int allocate_tables(AVCodecContext *avctx) return 0; } +static av_cold int init_frames(Vp3DecodeContext *s) +{ + s->current_frame.f = av_frame_alloc(); + s->last_frame.f = av_frame_alloc(); + s->golden_frame.f = av_frame_alloc(); + + if (!s->current_frame.f || !s->last_frame.f || !s->golden_frame.f) { + av_frame_free(&s->current_frame.f); + av_frame_free(&s->last_frame.f); + av_frame_free(&s->golden_frame.f); + return AVERROR(ENOMEM); + } + + return 0; +} + static av_cold int vp3_decode_init(AVCodecContext *avctx) { Vp3DecodeContext *s = avctx->priv_data; - int i, inter, plane; + int i, inter, plane, ret; int c_width; int c_height; int y_fragment_count, c_fragment_count; + ret = init_frames(s); + if (ret < 0) + return ret; + + avctx->internal->allocate_progress = 1; + if (avctx->codec_tag == MKTAG('V','P','3','0')) s->version = 0; else @@ -1821,12 +1839,6 @@ static av_cold int vp3_decode_init(AVCodecContext *avctx) &motion_vector_vlc_table[0][1], 2, 1, &motion_vector_vlc_table[0][0], 2, 1, 0); - for (i = 0; i < 3; i++) { - s->current_frame.data[i] = NULL; - s->last_frame.data[i] = NULL; - s->golden_frame.data[i] = NULL; - } - return allocate_tables(avctx); vlc_fail: @@ -1835,26 +1847,44 @@ vlc_fail: } /// Release and shuffle frames after decode finishes -static void update_frames(AVCodecContext *avctx) +static int update_frames(AVCodecContext *avctx) { Vp3DecodeContext *s = avctx->priv_data; + int ret = 0; - /* release the last frame, if it is allocated and if it is not the - * golden frame */ - if (s->last_frame.data[0] && s->last_frame.type != FF_BUFFER_TYPE_COPY) - ff_thread_release_buffer(avctx, &s->last_frame); /* shuffle frames (last = current) */ - s->last_frame= s->current_frame; + ff_thread_release_buffer(avctx, &s->last_frame); + ret = ff_thread_ref_frame(&s->last_frame, &s->current_frame); + if (ret < 0) + goto fail; if (s->keyframe) { - if (s->golden_frame.data[0]) - ff_thread_release_buffer(avctx, &s->golden_frame); - s->golden_frame = s->current_frame; - s->last_frame.type = FF_BUFFER_TYPE_COPY; + ff_thread_release_buffer(avctx, &s->golden_frame); + ret = ff_thread_ref_frame(&s->golden_frame, &s->current_frame); } - s->current_frame.data[0]= NULL; /* ensure that we catch any access to this released frame */ +fail: + ff_thread_release_buffer(avctx, &s->current_frame); + return ret; +} + +static int ref_frame(Vp3DecodeContext *s, ThreadFrame *dst, ThreadFrame *src) +{ + ff_thread_release_buffer(s->avctx, dst); + if (src->f->data[0]) + return ff_thread_ref_frame(dst, src); + return 0; +} + +static int ref_frames(Vp3DecodeContext *dst, Vp3DecodeContext *src) +{ + int ret; + if ((ret = ref_frame(dst, &dst->current_frame, &src->current_frame)) < 0 || + (ret = ref_frame(dst, &dst->golden_frame, &src->golden_frame)) < 0 || + (ret = ref_frame(dst, &dst->last_frame, &src->last_frame)) < 0) + return ret; + return 0; } static int vp3_update_thread_context(AVCodecContext *dst, const AVCodecContext *src) @@ -1864,17 +1894,17 @@ static int vp3_update_thread_context(AVCodecContext *dst, const AVCodecContext * #define copy_fields(to, from, start_field, end_field) memcpy(&to->start_field, &from->start_field, (char*)&to->end_field - (char*)&to->start_field) - if (!s1->current_frame.data[0] + if (!s1->current_frame.f->data[0] ||s->width != s1->width ||s->height!= s1->height) { if (s != s1) - copy_fields(s, s1, golden_frame, current_frame); + ref_frames(s, s1); return -1; } if (s != s1) { // init tables if the first frame hasn't been decoded - if (!s->current_frame.data[0]) { + if (!s->current_frame.f->data[0]) { int y_fragment_count, c_fragment_count; s->avctx = dst; err = allocate_tables(dst); @@ -1887,7 +1917,10 @@ static int vp3_update_thread_context(AVCodecContext *dst, const AVCodecContext * } // copy previous frame data - copy_fields(s, s1, golden_frame, dsp); + if ((err = ref_frames(s, s1)) < 0) + return err; + + s->keyframe = s1->keyframe; // copy qscale data if necessary for (i = 0; i < 3; i++) { @@ -1905,9 +1938,7 @@ static int vp3_update_thread_context(AVCodecContext *dst, const AVCodecContext * #undef copy_fields } - update_frames(dst); - - return 0; + return update_frames(dst); } static int vp3_decode_frame(AVCodecContext *avctx, @@ -1918,7 +1949,7 @@ static int vp3_decode_frame(AVCodecContext *avctx, int buf_size = avpkt->size; Vp3DecodeContext *s = avctx->priv_data; GetBitContext gb; - int i; + int i, ret; init_get_bits(&gb, buf, buf_size * 8); @@ -1960,15 +1991,14 @@ static int vp3_decode_frame(AVCodecContext *avctx, if (avctx->skip_frame >= AVDISCARD_NONKEY && !s->keyframe) return buf_size; - s->current_frame.reference = 3; - s->current_frame.pict_type = s->keyframe ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P; - if (ff_thread_get_buffer(avctx, &s->current_frame) < 0) { + s->current_frame.f->pict_type = s->keyframe ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P; + if (ff_thread_get_buffer(avctx, &s->current_frame, AV_GET_BUFFER_FLAG_REF) < 0) { av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n"); goto error; } if (!s->edge_emu_buffer) - s->edge_emu_buffer = av_malloc(9*FFABS(s->current_frame.linesize[0])); + s->edge_emu_buffer = av_malloc(9*FFABS(s->current_frame.f->linesize[0])); if (s->keyframe) { if (!s->theora) @@ -1989,17 +2019,17 @@ static int vp3_decode_frame(AVCodecContext *avctx, skip_bits(&gb, 2); /* reserved? */ } } else { - if (!s->golden_frame.data[0]) { + if (!s->golden_frame.f->data[0]) { av_log(s->avctx, AV_LOG_WARNING, "vp3: first frame not a keyframe\n"); - s->golden_frame.reference = 3; - s->golden_frame.pict_type = AV_PICTURE_TYPE_I; - if (ff_thread_get_buffer(avctx, &s->golden_frame) < 0) { + s->golden_frame.f->pict_type = AV_PICTURE_TYPE_I; + if (ff_thread_get_buffer(avctx, &s->golden_frame, AV_GET_BUFFER_FLAG_REF) < 0) { av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n"); goto error; } - s->last_frame = s->golden_frame; - s->last_frame.type = FF_BUFFER_TYPE_COPY; + ff_thread_release_buffer(avctx, &s->last_frame); + if ((ret = ff_thread_ref_frame(&s->last_frame, &s->golden_frame)) < 0) + goto error; ff_thread_report_progress(&s->last_frame, INT_MAX, 0); } } @@ -2033,7 +2063,7 @@ static int vp3_decode_frame(AVCodecContext *avctx, if (s->flipped_image) s->data_offset[i] = 0; else - s->data_offset[i] = (height-1) * s->current_frame.linesize[i]; + s->data_offset[i] = (height-1) * s->current_frame.f->linesize[i]; } s->last_slice_end = 0; @@ -2047,11 +2077,15 @@ static int vp3_decode_frame(AVCodecContext *avctx, } vp3_draw_horiz_band(s, s->avctx->height); + if ((ret = av_frame_ref(data, s->current_frame.f)) < 0) + return ret; *got_frame = 1; - *(AVFrame*)data= s->current_frame; - if (!HAVE_THREADS || !(s->avctx->active_thread_type&FF_THREAD_FRAME)) - update_frames(avctx); + if (!HAVE_THREADS || !(s->avctx->active_thread_type&FF_THREAD_FRAME)) { + ret = update_frames(avctx); + if (ret < 0) + return ret; + } return buf_size; @@ -2059,7 +2093,7 @@ error: ff_thread_report_progress(&s->current_frame, INT_MAX, 0); if (!HAVE_THREADS || !(s->avctx->active_thread_type&FF_THREAD_FRAME)) - avctx->release_buffer(avctx, &s->current_frame); + av_frame_unref(s->current_frame.f); return -1; } @@ -2113,7 +2147,7 @@ static int vp3_init_thread_copy(AVCodecContext *avctx) s->motion_val[1] = NULL; s->edge_emu_buffer = NULL; - return 0; + return init_frames(s); } #if CONFIG_THEORA_DECODER diff --git a/libavcodec/vp5.c b/libavcodec/vp5.c index 89333f3d92..742262be05 100644 --- a/libavcodec/vp5.c +++ b/libavcodec/vp5.c @@ -41,10 +41,10 @@ static int vp5_parse_header(VP56Context *s, const uint8_t *buf, int buf_size, int rows, cols; ff_vp56_init_range_decoder(&s->c, buf, buf_size); - s->framep[VP56_FRAME_CURRENT]->key_frame = !vp56_rac_get(c); + s->frames[VP56_FRAME_CURRENT]->key_frame = !vp56_rac_get(c); vp56_rac_get(c); ff_vp56_init_dequant(s, vp56_rac_gets(c, 6)); - if (s->framep[VP56_FRAME_CURRENT]->key_frame) + if (s->frames[VP56_FRAME_CURRENT]->key_frame) { vp56_rac_gets(c, 8); if(vp56_rac_gets(c, 5) > 5) @@ -138,7 +138,7 @@ static int vp5_parse_coeff_models(VP56Context *s) if (vp56_rac_get_prob(c, vp5_dccv_pct[pt][node])) { def_prob[node] = vp56_rac_gets_nn(c, 7); model->coeff_dccv[pt][node] = def_prob[node]; - } else if (s->framep[VP56_FRAME_CURRENT]->key_frame) { + } else if (s->frames[VP56_FRAME_CURRENT]->key_frame) { model->coeff_dccv[pt][node] = def_prob[node]; } @@ -149,7 +149,7 @@ static int vp5_parse_coeff_models(VP56Context *s) if (vp56_rac_get_prob(c, vp5_ract_pct[ct][pt][cg][node])) { def_prob[node] = vp56_rac_gets_nn(c, 7); model->coeff_ract[pt][ct][cg][node] = def_prob[node]; - } else if (s->framep[VP56_FRAME_CURRENT]->key_frame) { + } else if (s->frames[VP56_FRAME_CURRENT]->key_frame) { model->coeff_ract[pt][ct][cg][node] = def_prob[node]; } @@ -264,8 +264,10 @@ static void vp5_default_models_init(VP56Context *s) static av_cold int vp5_decode_init(AVCodecContext *avctx) { VP56Context *s = avctx->priv_data; + int ret; - ff_vp56_init(avctx, 1, 0); + if ((ret = ff_vp56_init(avctx, 1, 0)) < 0) + return ret; s->vp56_coord_div = vp5_coord_div; s->parse_vector_adjustment = vp5_parse_vector_adjustment; s->parse_coeff = vp5_parse_coeff; diff --git a/libavcodec/vp56.c b/libavcodec/vp56.c index 64f33c6dbe..b93f75da7e 100644 --- a/libavcodec/vp56.c +++ b/libavcodec/vp56.c @@ -36,7 +36,6 @@ void ff_vp56_init_dequant(VP56Context *s, int quantizer) s->quantizer = quantizer; s->dequant_dc = vp56_dc_dequant[quantizer] << 2; s->dequant_ac = vp56_ac_dequant[quantizer] << 2; - memset(s->qscale_table, quantizer, s->mb_width); } static int vp56_get_vectors_predictors(VP56Context *s, int row, int col, @@ -314,7 +313,7 @@ static void vp56_deblock_filter(VP56Context *s, uint8_t *yuv, static void vp56_mc(VP56Context *s, int b, int plane, uint8_t *src, int stride, int x, int y) { - uint8_t *dst=s->framep[VP56_FRAME_CURRENT]->data[plane]+s->block_offset[b]; + uint8_t *dst = s->frames[VP56_FRAME_CURRENT]->data[plane] + s->block_offset[b]; uint8_t *src_block; int src_offset; int overlap_offset = 0; @@ -325,7 +324,7 @@ static void vp56_mc(VP56Context *s, int b, int plane, uint8_t *src, if (s->avctx->skip_loop_filter >= AVDISCARD_ALL || (s->avctx->skip_loop_filter >= AVDISCARD_NONKEY - && !s->framep[VP56_FRAME_CURRENT]->key_frame)) + && !s->frames[VP56_FRAME_CURRENT]->key_frame)) deblock_filtering = 0; dx = s->mv[b].x / s->vp56_coord_div[b]; @@ -388,7 +387,7 @@ static void vp56_decode_mb(VP56Context *s, int row, int col, int is_alpha) VP56Frame ref_frame; int b, ab, b_max, plane, off; - if (s->framep[VP56_FRAME_CURRENT]->key_frame) + if (s->frames[VP56_FRAME_CURRENT]->key_frame) mb_type = VP56_MB_INTRA; else mb_type = vp56_decode_mv(s, row, col); @@ -398,8 +397,8 @@ static void vp56_decode_mb(VP56Context *s, int row, int col, int is_alpha) vp56_add_predictors_dc(s, ref_frame); - frame_current = s->framep[VP56_FRAME_CURRENT]; - frame_ref = s->framep[ref_frame]; + frame_current = s->frames[VP56_FRAME_CURRENT]; + frame_ref = s->frames[ref_frame]; if (mb_type != VP56_MB_INTRA && !frame_ref->data[0]) return; @@ -456,7 +455,7 @@ static void vp56_decode_mb(VP56Context *s, int row, int col, int is_alpha) static int vp56_size_changed(AVCodecContext *avctx) { VP56Context *s = avctx->priv_data; - int stride = s->framep[VP56_FRAME_CURRENT]->linesize[0]; + int stride = s->frames[VP56_FRAME_CURRENT]->linesize[0]; int i; s->plane_width[0] = s->plane_width[3] = avctx->coded_width; @@ -465,7 +464,7 @@ static int vp56_size_changed(AVCodecContext *avctx) s->plane_height[1] = s->plane_height[2] = avctx->coded_height/2; for (i=0; i<4; i++) - s->stride[i] = s->flip * s->framep[VP56_FRAME_CURRENT]->linesize[i]; + s->stride[i] = s->flip * s->frames[VP56_FRAME_CURRENT]->linesize[i]; s->mb_width = (avctx->coded_width +15) / 16; s->mb_height = (avctx->coded_height+15) / 16; @@ -476,7 +475,6 @@ static int vp56_size_changed(AVCodecContext *avctx) return -1; } - s->qscale_table = av_realloc(s->qscale_table, s->mb_width); s->above_blocks = av_realloc(s->above_blocks, (4*s->mb_width+6) * sizeof(*s->above_blocks)); s->macroblocks = av_realloc(s->macroblocks, @@ -495,9 +493,10 @@ int ff_vp56_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, { const uint8_t *buf = avpkt->data; VP56Context *s = avctx->priv_data; - AVFrame *const p = s->framep[VP56_FRAME_CURRENT]; + AVFrame *const p = s->frames[VP56_FRAME_CURRENT]; int remaining_buf_size = avpkt->size; int is_alpha, av_uninit(alpha_offset); + int res; if (s->has_alpha) { if (remaining_buf_size < 3) @@ -512,26 +511,21 @@ int ff_vp56_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, int mb_row, mb_col, mb_row_flip, mb_offset = 0; int block, y, uv, stride_y, stride_uv; int golden_frame = 0; - int res; s->modelp = &s->models[is_alpha]; res = s->parse_header(s, buf, remaining_buf_size, &golden_frame); if (res < 0) { int i; - for (i = 0; i < 4; i++) { - if (s->frames[i].data[0]) - avctx->release_buffer(avctx, &s->frames[i]); - } + for (i = 0; i < 4; i++) + av_frame_unref(s->frames[i]); return res; } if (res == VP56_SIZE_CHANGE) { int i; - for (i = 0; i < 4; i++) { - if (s->frames[i].data[0]) - avctx->release_buffer(avctx, &s->frames[i]); - } + for (i = 0; i < 4; i++) + av_frame_unref(s->frames[i]); if (is_alpha) { avcodec_set_dimensions(avctx, 0, 0); return -1; @@ -539,15 +533,14 @@ int ff_vp56_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, } if (!is_alpha) { - p->reference = 1; - if (ff_get_buffer(avctx, p) < 0) { + if (ff_get_buffer(avctx, p, AV_GET_BUFFER_FLAG_REF) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return -1; } if (res == VP56_SIZE_CHANGE) if (vp56_size_changed(avctx)) { - avctx->release_buffer(avctx, p); + av_frame_unref(p); return -1; } } @@ -631,44 +624,31 @@ int ff_vp56_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, next: if (p->key_frame || golden_frame) { - if (s->framep[VP56_FRAME_GOLDEN]->data[0] && - s->framep[VP56_FRAME_GOLDEN] != s->framep[VP56_FRAME_GOLDEN2]) - avctx->release_buffer(avctx, s->framep[VP56_FRAME_GOLDEN]); - s->framep[VP56_FRAME_GOLDEN] = p; + av_frame_unref(s->frames[VP56_FRAME_GOLDEN]); + if ((res = av_frame_ref(s->frames[VP56_FRAME_GOLDEN], p)) < 0) + return res; } if (s->has_alpha) { - FFSWAP(AVFrame *, s->framep[VP56_FRAME_GOLDEN], - s->framep[VP56_FRAME_GOLDEN2]); + FFSWAP(AVFrame *, s->frames[VP56_FRAME_GOLDEN], + s->frames[VP56_FRAME_GOLDEN2]); buf += alpha_offset; remaining_buf_size -= alpha_offset; } } - if (s->framep[VP56_FRAME_PREVIOUS] == s->framep[VP56_FRAME_GOLDEN] || - s->framep[VP56_FRAME_PREVIOUS] == s->framep[VP56_FRAME_GOLDEN2]) { - if (s->framep[VP56_FRAME_UNUSED] != s->framep[VP56_FRAME_GOLDEN] && - s->framep[VP56_FRAME_UNUSED] != s->framep[VP56_FRAME_GOLDEN2]) - FFSWAP(AVFrame *, s->framep[VP56_FRAME_PREVIOUS], - s->framep[VP56_FRAME_UNUSED]); - else - FFSWAP(AVFrame *, s->framep[VP56_FRAME_PREVIOUS], - s->framep[VP56_FRAME_UNUSED2]); - } else if (s->framep[VP56_FRAME_PREVIOUS]->data[0]) - avctx->release_buffer(avctx, s->framep[VP56_FRAME_PREVIOUS]); - FFSWAP(AVFrame *, s->framep[VP56_FRAME_CURRENT], - s->framep[VP56_FRAME_PREVIOUS]); + av_frame_unref(s->frames[VP56_FRAME_PREVIOUS]); + FFSWAP(AVFrame *, s->frames[VP56_FRAME_CURRENT], + s->frames[VP56_FRAME_PREVIOUS]); - p->qstride = 0; - p->qscale_table = s->qscale_table; - p->qscale_type = FF_QSCALE_TYPE_VP56; - *(AVFrame*)data = *p; + if ((res = av_frame_ref(data, p)) < 0) + return res; *got_frame = 1; return avpkt->size; } -av_cold void ff_vp56_init(AVCodecContext *avctx, int flip, int has_alpha) +av_cold int ff_vp56_init(AVCodecContext *avctx, int flip, int has_alpha) { VP56Context *s = avctx->priv_data; int i; @@ -684,10 +664,13 @@ av_cold void ff_vp56_init(AVCodecContext *avctx, int flip, int has_alpha) ff_init_scantable_permutation(s->dsp.idct_permutation, s->vp3dsp.idct_perm); ff_init_scantable(s->dsp.idct_permutation, &s->scantable,ff_zigzag_direct); - for (i=0; i<4; i++) - s->framep[i] = &s->frames[i]; - s->framep[VP56_FRAME_UNUSED] = s->framep[VP56_FRAME_GOLDEN]; - s->framep[VP56_FRAME_UNUSED2] = s->framep[VP56_FRAME_GOLDEN2]; + for (i = 0; i < FF_ARRAY_ELEMS(s->frames); i++) { + s->frames[i] = av_frame_alloc(); + if (!s->frames[i]) { + ff_vp56_free(avctx); + return AVERROR(ENOMEM); + } + } s->edge_emu_buffer_alloc = NULL; s->above_blocks = NULL; @@ -707,21 +690,21 @@ av_cold void ff_vp56_init(AVCodecContext *avctx, int flip, int has_alpha) s->frbi = 0; s->srbi = 2; } + + return 0; } av_cold int ff_vp56_free(AVCodecContext *avctx) { VP56Context *s = avctx->priv_data; + int i; - av_freep(&s->qscale_table); av_freep(&s->above_blocks); av_freep(&s->macroblocks); av_freep(&s->edge_emu_buffer_alloc); - if (s->framep[VP56_FRAME_GOLDEN]->data[0]) - avctx->release_buffer(avctx, s->framep[VP56_FRAME_GOLDEN]); - if (s->framep[VP56_FRAME_GOLDEN2]->data[0]) - avctx->release_buffer(avctx, s->framep[VP56_FRAME_GOLDEN2]); - if (s->framep[VP56_FRAME_PREVIOUS]->data[0]) - avctx->release_buffer(avctx, s->framep[VP56_FRAME_PREVIOUS]); + + for (i = 0; i < FF_ARRAY_ELEMS(s->frames); i++) + av_frame_free(&s->frames[i]); + return 0; } diff --git a/libavcodec/vp56.h b/libavcodec/vp56.h index 8c6ba14ada..80ede6a0aa 100644 --- a/libavcodec/vp56.h +++ b/libavcodec/vp56.h @@ -101,8 +101,7 @@ struct vp56_context { VP3DSPContext vp3dsp; VP56DSPContext vp56dsp; ScanTable scantable; - AVFrame frames[4]; - AVFrame *framep[6]; + AVFrame *frames[4]; uint8_t *edge_emu_buffer_alloc; uint8_t *edge_emu_buffer; VP56RangeCoder c; @@ -120,7 +119,6 @@ struct vp56_context { int quantizer; uint16_t dequant_dc; uint16_t dequant_ac; - int8_t *qscale_table; /* DC predictors management */ VP56RefDc *above_blocks; @@ -179,7 +177,7 @@ struct vp56_context { }; -void ff_vp56_init(AVCodecContext *avctx, int flip, int has_alpha); +int ff_vp56_init(AVCodecContext *avctx, int flip, int has_alpha); int ff_vp56_free(AVCodecContext *avctx); void ff_vp56_init_dequant(VP56Context *s, int quantizer); int ff_vp56_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, diff --git a/libavcodec/vp56data.h b/libavcodec/vp56data.h index 0535425d3d..ee3832293d 100644 --- a/libavcodec/vp56data.h +++ b/libavcodec/vp56data.h @@ -34,8 +34,6 @@ typedef enum { VP56_FRAME_PREVIOUS = 1, VP56_FRAME_GOLDEN = 2, VP56_FRAME_GOLDEN2 = 3, - VP56_FRAME_UNUSED = 4, - VP56_FRAME_UNUSED2 = 5, } VP56Frame; typedef enum { diff --git a/libavcodec/vp6.c b/libavcodec/vp6.c index b824e3b1cd..30b489dfca 100644 --- a/libavcodec/vp6.c +++ b/libavcodec/vp6.c @@ -54,10 +54,10 @@ static int vp6_parse_header(VP56Context *s, const uint8_t *buf, int buf_size, int res = 0; int separated_coeff = buf[0] & 1; - s->framep[VP56_FRAME_CURRENT]->key_frame = !(buf[0] & 0x80); + s->frames[VP56_FRAME_CURRENT]->key_frame = !(buf[0] & 0x80); ff_vp56_init_dequant(s, (buf[0] >> 1) & 0x3F); - if (s->framep[VP56_FRAME_CURRENT]->key_frame) { + if (s->frames[VP56_FRAME_CURRENT]->key_frame) { sub_version = buf[1] >> 3; if (sub_version > 8) return AVERROR_INVALIDDATA; @@ -143,7 +143,7 @@ static int vp6_parse_header(VP56Context *s, const uint8_t *buf, int buf_size, buf += coeff_offset; buf_size -= coeff_offset; if (buf_size < 0) { - if (s->framep[VP56_FRAME_CURRENT]->key_frame) + if (s->frames[VP56_FRAME_CURRENT]->key_frame) avcodec_set_dimensions(s->avctx, 0, 0); return AVERROR_INVALIDDATA; } @@ -258,7 +258,7 @@ static int vp6_parse_coeff_models(VP56Context *s) if (vp56_rac_get_prob(c, vp6_dccv_pct[pt][node])) { def_prob[node] = vp56_rac_gets_nn(c, 7); model->coeff_dccv[pt][node] = def_prob[node]; - } else if (s->framep[VP56_FRAME_CURRENT]->key_frame) { + } else if (s->frames[VP56_FRAME_CURRENT]->key_frame) { model->coeff_dccv[pt][node] = def_prob[node]; } @@ -281,7 +281,7 @@ static int vp6_parse_coeff_models(VP56Context *s) if (vp56_rac_get_prob(c, vp6_ract_pct[ct][pt][cg][node])) { def_prob[node] = vp56_rac_gets_nn(c, 7); model->coeff_ract[pt][ct][cg][node] = def_prob[node]; - } else if (s->framep[VP56_FRAME_CURRENT]->key_frame) { + } else if (s->frames[VP56_FRAME_CURRENT]->key_frame) { model->coeff_ract[pt][ct][cg][node] = def_prob[node]; } @@ -592,9 +592,12 @@ static void vp6_filter(VP56Context *s, uint8_t *dst, uint8_t *src, static av_cold int vp6_decode_init(AVCodecContext *avctx) { VP56Context *s = avctx->priv_data; + int ret; + + if ((ret = ff_vp56_init(avctx, avctx->codec->id == AV_CODEC_ID_VP6, + avctx->codec->id == AV_CODEC_ID_VP6A)) < 0) + return ret; - ff_vp56_init(avctx, avctx->codec->id == AV_CODEC_ID_VP6, - avctx->codec->id == AV_CODEC_ID_VP6A); s->vp56_coord_div = vp6_coord_div; s->parse_vector_adjustment = vp6_parse_vector_adjustment; s->filter = vp6_filter; diff --git a/libavcodec/vp8.c b/libavcodec/vp8.c index e6b0071ce6..4d4ff6ca2d 100644 --- a/libavcodec/vp8.c +++ b/libavcodec/vp8.c @@ -52,64 +52,59 @@ static void free_buffers(VP8Context *s) s->macroblocks = NULL; } -static int vp8_alloc_frame(VP8Context *s, AVFrame *f) +static int vp8_alloc_frame(VP8Context *s, VP8Frame *f, int ref) { int ret; - if ((ret = ff_thread_get_buffer(s->avctx, f)) < 0) + if ((ret = ff_thread_get_buffer(s->avctx, &f->tf, + ref ? AV_GET_BUFFER_FLAG_REF : 0)) < 0) return ret; - if (s->num_maps_to_be_freed && !s->maps_are_invalid) { - f->ref_index[0] = s->segmentation_maps[--s->num_maps_to_be_freed]; - } else if (!(f->ref_index[0] = av_mallocz(s->mb_width * s->mb_height))) { - ff_thread_release_buffer(s->avctx, f); + if (!(f->seg_map = av_buffer_allocz(s->mb_width * s->mb_height))) { + ff_thread_release_buffer(s->avctx, &f->tf); return AVERROR(ENOMEM); } return 0; } -static void vp8_release_frame(VP8Context *s, AVFrame *f, int prefer_delayed_free, int can_direct_free) +static void vp8_release_frame(VP8Context *s, VP8Frame *f) { - if (f->ref_index[0]) { - if (prefer_delayed_free) { - /* Upon a size change, we want to free the maps but other threads may still - * be using them, so queue them. Upon a seek, all threads are inactive so - * we want to cache one to prevent re-allocation in the next decoding - * iteration, but the rest we can free directly. */ - int max_queued_maps = can_direct_free ? 1 : FF_ARRAY_ELEMS(s->segmentation_maps); - if (s->num_maps_to_be_freed < max_queued_maps) { - s->segmentation_maps[s->num_maps_to_be_freed++] = f->ref_index[0]; - } else if (can_direct_free) /* vp8_decode_flush(), but our queue is full */ { - av_free(f->ref_index[0]); - } /* else: MEMLEAK (should never happen, but better that than crash) */ - f->ref_index[0] = NULL; - } else /* vp8_decode_free() */ { - av_free(f->ref_index[0]); - } - } - ff_thread_release_buffer(s->avctx, f); + av_buffer_unref(&f->seg_map); + ff_thread_release_buffer(s->avctx, &f->tf); } -static void vp8_decode_flush_impl(AVCodecContext *avctx, - int prefer_delayed_free, int can_direct_free, int free_mem) +static int vp8_ref_frame(VP8Context *s, VP8Frame *dst, VP8Frame *src) +{ + int ret; + + vp8_release_frame(s, dst); + + if ((ret = ff_thread_ref_frame(&dst->tf, &src->tf)) < 0) + return ret; + if (src->seg_map && + !(dst->seg_map = av_buffer_ref(src->seg_map))) { + vp8_release_frame(s, dst); + return AVERROR(ENOMEM); + } + + return 0; +} + + +static void vp8_decode_flush_impl(AVCodecContext *avctx, int free_mem) { VP8Context *s = avctx->priv_data; int i; - if (!avctx->internal->is_copy) { - for (i = 0; i < 5; i++) - if (s->frames[i].data[0]) - vp8_release_frame(s, &s->frames[i], prefer_delayed_free, can_direct_free); - } + for (i = 0; i < FF_ARRAY_ELEMS(s->frames); i++) + vp8_release_frame(s, &s->frames[i]); memset(s->framep, 0, sizeof(s->framep)); - if (free_mem) { + if (free_mem) free_buffers(s); - s->maps_are_invalid = 1; - } } static void vp8_decode_flush(AVCodecContext *avctx) { - vp8_decode_flush_impl(avctx, 1, 1, 0); + vp8_decode_flush_impl(avctx, 0); } static int update_dimensions(VP8Context *s, int width, int height) @@ -122,7 +117,7 @@ static int update_dimensions(VP8Context *s, int width, int height) if (av_image_check_size(width, height, 0, s->avctx)) return AVERROR_INVALIDDATA; - vp8_decode_flush_impl(s->avctx, 1, 0, 1); + vp8_decode_flush_impl(s->avctx, 1); avcodec_set_dimensions(s->avctx, width, height); } @@ -1178,12 +1173,12 @@ static const uint8_t subpel_idx[3][8] = { */ static av_always_inline void vp8_mc_luma(VP8Context *s, VP8ThreadData *td, uint8_t *dst, - AVFrame *ref, const VP56mv *mv, + ThreadFrame *ref, const VP56mv *mv, int x_off, int y_off, int block_w, int block_h, int width, int height, int linesize, vp8_mc_func mc_func[3][3]) { - uint8_t *src = ref->data[0]; + uint8_t *src = ref->f->data[0]; if (AV_RN32A(mv)) { @@ -1229,11 +1224,11 @@ void vp8_mc_luma(VP8Context *s, VP8ThreadData *td, uint8_t *dst, */ static av_always_inline void vp8_mc_chroma(VP8Context *s, VP8ThreadData *td, uint8_t *dst1, uint8_t *dst2, - AVFrame *ref, const VP56mv *mv, int x_off, int y_off, + ThreadFrame *ref, const VP56mv *mv, int x_off, int y_off, int block_w, int block_h, int width, int height, int linesize, vp8_mc_func mc_func[3][3]) { - uint8_t *src1 = ref->data[1], *src2 = ref->data[2]; + uint8_t *src1 = ref->f->data[1], *src2 = ref->f->data[2]; if (AV_RN32A(mv)) { int mx = mv->x&7, mx_idx = subpel_idx[0][mx]; @@ -1272,7 +1267,7 @@ void vp8_mc_chroma(VP8Context *s, VP8ThreadData *td, uint8_t *dst1, uint8_t *dst static av_always_inline void vp8_mc_part(VP8Context *s, VP8ThreadData *td, uint8_t *dst[3], - AVFrame *ref_frame, int x_off, int y_off, + ThreadFrame *ref_frame, int x_off, int y_off, int bx_off, int by_off, int block_w, int block_h, int width, int height, VP56mv *mv) @@ -1310,7 +1305,7 @@ static av_always_inline void prefetch_motion(VP8Context *s, VP8Macroblock *mb, i int x_off = mb_x << 4, y_off = mb_y << 4; int mx = (mb->mv.x>>2) + x_off + 8; int my = (mb->mv.y>>2) + y_off; - uint8_t **src= s->framep[ref]->data; + uint8_t **src= s->framep[ref]->tf.f->data; int off= mx + (my + (mb_x&3)*4)*s->linesize + 64; /* For threading, a ff_thread_await_progress here might be useful, but * it actually slows down the decoder. Since a bad prefetch doesn't @@ -1330,7 +1325,7 @@ void inter_predict(VP8Context *s, VP8ThreadData *td, uint8_t *dst[3], { int x_off = mb_x << 4, y_off = mb_y << 4; int width = 16*s->mb_width, height = 16*s->mb_height; - AVFrame *ref = s->framep[mb->ref_frame]; + ThreadFrame *ref = &s->framep[mb->ref_frame]->tf; VP56mv *bmv = mb->bmv; switch (mb->partitioning) { @@ -1589,17 +1584,9 @@ static av_always_inline void filter_mb_simple(VP8Context *s, uint8_t *dst, VP8Fi } } -static void release_queued_segmaps(VP8Context *s, int is_close) -{ - int leave_behind = is_close ? 0 : !s->maps_are_invalid; - while (s->num_maps_to_be_freed > leave_behind) - av_freep(&s->segmentation_maps[--s->num_maps_to_be_freed]); - s->maps_are_invalid = 0; -} - #define MARGIN (16 << 2) -static void vp8_decode_mv_mb_modes(AVCodecContext *avctx, AVFrame *curframe, - AVFrame *prev_frame) +static void vp8_decode_mv_mb_modes(AVCodecContext *avctx, VP8Frame *curframe, + VP8Frame *prev_frame) { VP8Context *s = avctx->priv_data; int mb_x, mb_y; @@ -1617,8 +1604,9 @@ static void vp8_decode_mv_mb_modes(AVCodecContext *avctx, AVFrame *curframe, for (mb_x = 0; mb_x < s->mb_width; mb_x++, mb_xy++, mb++) { if (mb_y == 0) AV_WN32A((mb-s->mb_width-1)->intra4x4_pred_mode_top, DC_PRED*0x01010101); - decode_mb_mode(s, mb, mb_x, mb_y, curframe->ref_index[0] + mb_xy, - prev_frame && prev_frame->ref_index[0] ? prev_frame->ref_index[0] + mb_xy : NULL, 1); + decode_mb_mode(s, mb, mb_x, mb_y, curframe->seg_map->data + mb_xy, + prev_frame && prev_frame->seg_map ? + prev_frame->seg_map->data + mb_xy : NULL, 1); s->mv_min.x -= 64; s->mv_max.x -= 64; } @@ -1672,13 +1660,13 @@ static void vp8_decode_mb_row_no_filter(AVCodecContext *avctx, void *tdata, int mb_y = td->thread_mb_pos>>16; int i, y, mb_x, mb_xy = mb_y*s->mb_width; int num_jobs = s->num_jobs; - AVFrame *curframe = s->curframe, *prev_frame = s->prev_frame; + VP8Frame *curframe = s->curframe, *prev_frame = s->prev_frame; VP56RangeCoder *c = &s->coeff_partition[mb_y & (s->num_coeff_partitions-1)]; VP8Macroblock *mb; uint8_t *dst[3] = { - curframe->data[0] + 16*mb_y*s->linesize, - curframe->data[1] + 8*mb_y*s->uvlinesize, - curframe->data[2] + 8*mb_y*s->uvlinesize + curframe->tf.f->data[0] + 16*mb_y*s->linesize, + curframe->tf.f->data[1] + 8*mb_y*s->uvlinesize, + curframe->tf.f->data[2] + 8*mb_y*s->uvlinesize }; if (mb_y == 0) prev_td = td; else prev_td = &s->thread_data[(jobnr + num_jobs - 1)%num_jobs]; @@ -1697,7 +1685,7 @@ static void vp8_decode_mb_row_no_filter(AVCodecContext *avctx, void *tdata, if (!(avctx->flags & CODEC_FLAG_EMU_EDGE)) { for (i = 0; i < 3; i++) for (y = 0; y < 16>>!!i; y++) - dst[i][y*curframe->linesize[i]-1] = 129; + dst[i][y*curframe->tf.f->linesize[i]-1] = 129; if (mb_y == 1) { s->top_border[0][15] = s->top_border[0][23] = s->top_border[0][31] = 129; } @@ -1720,8 +1708,9 @@ static void vp8_decode_mb_row_no_filter(AVCodecContext *avctx, void *tdata, s->vdsp.prefetch(dst[1] + (mb_x&7)*s->uvlinesize + 64, dst[2] - dst[1], 2); if (!s->mb_layout) - decode_mb_mode(s, mb, mb_x, mb_y, curframe->ref_index[0] + mb_xy, - prev_frame && prev_frame->ref_index[0] ? prev_frame->ref_index[0] + mb_xy : NULL, 0); + decode_mb_mode(s, mb, mb_x, mb_y, curframe->seg_map->data + mb_xy, + prev_frame && prev_frame->seg_map ? + prev_frame->seg_map->data + mb_xy : NULL, 0); prefetch_motion(s, mb, mb_x, mb_y, mb_xy, VP56_FRAME_PREVIOUS); @@ -1780,7 +1769,7 @@ static void vp8_filter_mb_row(AVCodecContext *avctx, void *tdata, VP8Context *s = avctx->priv_data; VP8ThreadData *td = &s->thread_data[threadnr]; int mb_x, mb_y = td->thread_mb_pos>>16, num_jobs = s->num_jobs; - AVFrame *curframe = s->curframe; + AVFrame *curframe = s->curframe->tf.f; VP8Macroblock *mb; VP8ThreadData *prev_td, *next_td; uint8_t *dst[3] = { @@ -1834,7 +1823,7 @@ static int vp8_decode_mb_row_sliced(AVCodecContext *avctx, void *tdata, VP8Context *s = avctx->priv_data; VP8ThreadData *td = &s->thread_data[jobnr]; VP8ThreadData *next_td = NULL, *prev_td = NULL; - AVFrame *curframe = s->curframe; + VP8Frame *curframe = s->curframe; int mb_y, num_jobs = s->num_jobs; td->thread_nr = threadnr; for (mb_y = jobnr; mb_y < s->mb_height; mb_y += num_jobs) { @@ -1849,7 +1838,7 @@ static int vp8_decode_mb_row_sliced(AVCodecContext *avctx, void *tdata, s->mv_max.y -= 64; if (avctx->active_thread_type == FF_THREAD_FRAME) - ff_thread_report_progress(curframe, mb_y, 0); + ff_thread_report_progress(&curframe->tf, mb_y, 0); } return 0; @@ -1861,9 +1850,7 @@ static int vp8_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, VP8Context *s = avctx->priv_data; int ret, i, referenced, num_jobs; enum AVDiscard skip_thresh; - AVFrame *av_uninit(curframe), *prev_frame; - - release_queued_segmaps(s, 0); + VP8Frame *av_uninit(curframe), *prev_frame; if ((ret = decode_frame_header(s, avpkt->data, avpkt->size)) < 0) goto err; @@ -1885,12 +1872,12 @@ static int vp8_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, // release no longer referenced frames for (i = 0; i < 5; i++) - if (s->frames[i].data[0] && + if (s->frames[i].tf.f->data[0] && &s->frames[i] != prev_frame && &s->frames[i] != s->framep[VP56_FRAME_PREVIOUS] && &s->frames[i] != s->framep[VP56_FRAME_GOLDEN] && &s->frames[i] != s->framep[VP56_FRAME_GOLDEN2]) - vp8_release_frame(s, &s->frames[i], 1, 0); + vp8_release_frame(s, &s->frames[i]); // find a free buffer for (i = 0; i < 5; i++) @@ -1905,8 +1892,8 @@ static int vp8_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, av_log(avctx, AV_LOG_FATAL, "Ran out of free frames!\n"); abort(); } - if (curframe->data[0]) - vp8_release_frame(s, curframe, 1, 0); + if (curframe->tf.f->data[0]) + vp8_release_frame(s, curframe); // Given that arithmetic probabilities are updated every frame, it's quite likely // that the values we have on a random interframe are complete junk if we didn't @@ -1919,10 +1906,9 @@ static int vp8_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, goto err; } - curframe->key_frame = s->keyframe; - curframe->pict_type = s->keyframe ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P; - curframe->reference = referenced ? 3 : 0; - if ((ret = vp8_alloc_frame(s, curframe))) { + curframe->tf.f->key_frame = s->keyframe; + curframe->tf.f->pict_type = s->keyframe ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P; + if ((ret = vp8_alloc_frame(s, curframe, referenced))) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed!\n"); goto err; } @@ -1947,8 +1933,8 @@ static int vp8_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, ff_thread_finish_setup(avctx); - s->linesize = curframe->linesize[0]; - s->uvlinesize = curframe->linesize[1]; + s->linesize = curframe->tf.f->linesize[0]; + s->uvlinesize = curframe->tf.f->linesize[1]; if (!s->thread_data[0].edge_emu_buffer) for (i = 0; i < MAX_THREADS; i++) @@ -1973,7 +1959,7 @@ static int vp8_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, // Make sure the previous frame has read its segmentation map, // if we re-use the same map. if (prev_frame && s->segmentation.enabled && !s->segmentation.update_map) - ff_thread_await_progress(prev_frame, 1, 0); + ff_thread_await_progress(&prev_frame->tf, 1, 0); if (s->mb_layout == 1) vp8_decode_mv_mb_modes(avctx, curframe, prev_frame); @@ -1993,7 +1979,7 @@ static int vp8_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, } avctx->execute2(avctx, vp8_decode_mb_row_sliced, s->thread_data, NULL, num_jobs); - ff_thread_report_progress(curframe, INT_MAX, 0); + ff_thread_report_progress(&curframe->tf, INT_MAX, 0); memcpy(&s->framep[0], &s->next_framep[0], sizeof(s->framep[0]) * 4); skip_decode: @@ -2003,7 +1989,8 @@ skip_decode: s->prob[0] = s->prob[1]; if (!s->invisible) { - *(AVFrame*)data = *curframe; + if ((ret = av_frame_ref(data, curframe->tf.f)) < 0) + return ret; *got_frame = 1; } @@ -2013,33 +2000,62 @@ err: return ret; } +static av_cold int vp8_decode_free(AVCodecContext *avctx) +{ + VP8Context *s = avctx->priv_data; + int i; + + vp8_decode_flush_impl(avctx, 1); + for (i = 0; i < FF_ARRAY_ELEMS(s->frames); i++) + av_frame_free(&s->frames[i].tf.f); + + return 0; +} + +static av_cold int vp8_init_frames(VP8Context *s) +{ + int i; + for (i = 0; i < FF_ARRAY_ELEMS(s->frames); i++) { + s->frames[i].tf.f = av_frame_alloc(); + if (!s->frames[i].tf.f) + return AVERROR(ENOMEM); + } + return 0; +} + static av_cold int vp8_decode_init(AVCodecContext *avctx) { VP8Context *s = avctx->priv_data; + int ret; s->avctx = avctx; avctx->pix_fmt = AV_PIX_FMT_YUV420P; + avctx->internal->allocate_progress = 1; ff_videodsp_init(&s->vdsp, 8); ff_h264_pred_init(&s->hpc, AV_CODEC_ID_VP8, 8, 1); ff_vp8dsp_init(&s->vp8dsp); - return 0; -} + if ((ret = vp8_init_frames(s)) < 0) { + vp8_decode_free(avctx); + return ret; + } -static av_cold int vp8_decode_free(AVCodecContext *avctx) -{ - vp8_decode_flush_impl(avctx, 0, 1, 1); - release_queued_segmaps(avctx->priv_data, 1); return 0; } static av_cold int vp8_decode_init_thread_copy(AVCodecContext *avctx) { VP8Context *s = avctx->priv_data; + int ret; s->avctx = avctx; + if ((ret = vp8_init_frames(s)) < 0) { + vp8_decode_free(avctx); + return ret; + } + return 0; } @@ -2049,11 +2065,11 @@ static av_cold int vp8_decode_init_thread_copy(AVCodecContext *avctx) static int vp8_decode_update_thread_context(AVCodecContext *dst, const AVCodecContext *src) { VP8Context *s = dst->priv_data, *s_src = src->priv_data; + int i; if (s->macroblocks_base && (s_src->mb_width != s->mb_width || s_src->mb_height != s->mb_height)) { free_buffers(s); - s->maps_are_invalid = 1; s->mb_width = s_src->mb_width; s->mb_height = s_src->mb_height; } @@ -2063,7 +2079,14 @@ static int vp8_decode_update_thread_context(AVCodecContext *dst, const AVCodecCo s->lf_delta = s_src->lf_delta; memcpy(s->sign_bias, s_src->sign_bias, sizeof(s->sign_bias)); - memcpy(&s->frames, &s_src->frames, sizeof(s->frames)); + for (i = 0; i < FF_ARRAY_ELEMS(s_src->frames); i++) { + if (s_src->frames[i].tf.f->data[0]) { + int ret = vp8_ref_frame(s, &s->frames[i], &s_src->frames[i]); + if (ret < 0) + return ret; + } + } + s->framep[0] = REBASE(s_src->next_framep[0]); s->framep[1] = REBASE(s_src->next_framep[1]); s->framep[2] = REBASE(s_src->next_framep[2]); diff --git a/libavcodec/vp8.h b/libavcodec/vp8.h index 392d0b44c9..8631c8f5db 100644 --- a/libavcodec/vp8.h +++ b/libavcodec/vp8.h @@ -26,10 +26,13 @@ #ifndef AVCODEC_VP8_H #define AVCODEC_VP8_H +#include "libavutil/buffer.h" + #include "vp56.h" #include "vp56data.h" #include "vp8dsp.h" #include "h264pred.h" +#include "thread.h" #if HAVE_PTHREADS #include #elif HAVE_W32THREADS @@ -122,14 +125,19 @@ typedef struct VP8ThreadData { VP8FilterStrength *filter_strength; } VP8ThreadData; +typedef struct VP8Frame { + ThreadFrame tf; + AVBufferRef *seg_map; +} VP8Frame; + #define MAX_THREADS 8 typedef struct VP8Context { VP8ThreadData *thread_data; AVCodecContext *avctx; - AVFrame *framep[4]; - AVFrame *next_framep[4]; - AVFrame *curframe; - AVFrame *prev_frame; + VP8Frame *framep[4]; + VP8Frame *next_framep[4]; + VP8Frame *curframe; + VP8Frame *prev_frame; uint16_t mb_width; /* number of horizontal MB */ uint16_t mb_height; /* number of vertical MB */ @@ -251,17 +259,8 @@ typedef struct VP8Context { VP8DSPContext vp8dsp; H264PredContext hpc; vp8_mc_func put_pixels_tab[3][3][3]; - AVFrame frames[5]; + VP8Frame frames[5]; - /** - * A list of segmentation_map buffers that are to be free()'ed in - * the next decoding iteration. We can't free() them right away - * because the map may still be used by subsequent decoding threads. - * Unused if frame threading is off. - */ - uint8_t *segmentation_maps[5]; - int num_maps_to_be_freed; - int maps_are_invalid; int num_jobs; /** * This describes the macroblock memory layout. diff --git a/libavcodec/vqavideo.c b/libavcodec/vqavideo.c index ae854cda56..ed4d8147cb 100644 --- a/libavcodec/vqavideo.c +++ b/libavcodec/vqavideo.c @@ -94,7 +94,6 @@ typedef struct VqaContext { AVCodecContext *avctx; - AVFrame frame; GetByteContext gb; uint32_t palette[PALETTE_COUNT]; @@ -188,8 +187,6 @@ static av_cold int vqa_decode_init(AVCodecContext *avctx) } s->next_codebook_buffer_index = 0; - s->frame.data[0] = NULL; - return 0; fail: av_freep(&s->codebook); @@ -303,7 +300,7 @@ static int decode_format80(GetByteContext *gb, int src_size, return 0; // let's display what we decoded anyway } -static int vqa_decode_chunk(VqaContext *s) +static int vqa_decode_chunk(VqaContext *s, AVFrame *frame) { unsigned int chunk_type; unsigned int chunk_size; @@ -471,7 +468,7 @@ static int vqa_decode_chunk(VqaContext *s) index_shift = 3; for (y = 0; y < s->height; y += s->vector_height) { for (x = 0; x < s->width; x += 4, lobytes++, hibytes++) { - pixel_ptr = y * s->frame.linesize[0] + x; + pixel_ptr = y * frame->linesize[0] + x; /* get the vector index, the method for which varies according to * VQA file version */ @@ -486,11 +483,11 @@ static int vqa_decode_chunk(VqaContext *s) /* uniform color fill - a quick hack */ if (hibyte == 0xFF) { while (lines--) { - s->frame.data[0][pixel_ptr + 0] = 255 - lobyte; - s->frame.data[0][pixel_ptr + 1] = 255 - lobyte; - s->frame.data[0][pixel_ptr + 2] = 255 - lobyte; - s->frame.data[0][pixel_ptr + 3] = 255 - lobyte; - pixel_ptr += s->frame.linesize[0]; + frame->data[0][pixel_ptr + 0] = 255 - lobyte; + frame->data[0][pixel_ptr + 1] = 255 - lobyte; + frame->data[0][pixel_ptr + 2] = 255 - lobyte; + frame->data[0][pixel_ptr + 3] = 255 - lobyte; + pixel_ptr += frame->linesize[0]; } lines=0; } @@ -511,11 +508,11 @@ static int vqa_decode_chunk(VqaContext *s) } while (lines--) { - s->frame.data[0][pixel_ptr + 0] = s->codebook[vector_index++]; - s->frame.data[0][pixel_ptr + 1] = s->codebook[vector_index++]; - s->frame.data[0][pixel_ptr + 2] = s->codebook[vector_index++]; - s->frame.data[0][pixel_ptr + 3] = s->codebook[vector_index++]; - pixel_ptr += s->frame.linesize[0]; + frame->data[0][pixel_ptr + 0] = s->codebook[vector_index++]; + frame->data[0][pixel_ptr + 1] = s->codebook[vector_index++]; + frame->data[0][pixel_ptr + 2] = s->codebook[vector_index++]; + frame->data[0][pixel_ptr + 3] = s->codebook[vector_index++]; + pixel_ptr += frame->linesize[0]; } } } @@ -596,26 +593,23 @@ static int vqa_decode_frame(AVCodecContext *avctx, AVPacket *avpkt) { VqaContext *s = avctx->priv_data; + AVFrame *frame = data; int res; - if (s->frame.data[0]) - avctx->release_buffer(avctx, &s->frame); - - if ((res = ff_get_buffer(avctx, &s->frame)) < 0) { + if ((res = ff_get_buffer(avctx, frame, 0)) < 0) { av_log(s->avctx, AV_LOG_ERROR, " VQA Video: get_buffer() failed\n"); return res; } bytestream2_init(&s->gb, avpkt->data, avpkt->size); - if ((res = vqa_decode_chunk(s)) < 0) + if ((res = vqa_decode_chunk(s, frame)) < 0) return res; /* make the palette available on the way out */ - memcpy(s->frame.data[1], s->palette, PALETTE_COUNT * 4); - s->frame.palette_has_changed = 1; + memcpy(frame->data[1], s->palette, PALETTE_COUNT * 4); + frame->palette_has_changed = 1; *got_frame = 1; - *(AVFrame*)data = s->frame; /* report that the buffer was completely consumed */ return avpkt->size; @@ -629,9 +623,6 @@ static av_cold int vqa_decode_end(AVCodecContext *avctx) av_freep(&s->next_codebook_buffer); av_freep(&s->decode_buffer); - if (s->frame.data[0]) - avctx->release_buffer(avctx, &s->frame); - return 0; } diff --git a/libavcodec/wavpack.c b/libavcodec/wavpack.c index ca639ee54b..37e87686ca 100644 --- a/libavcodec/wavpack.c +++ b/libavcodec/wavpack.c @@ -1205,7 +1205,7 @@ static int wavpack_decode_frame(AVCodecContext *avctx, void *data, /* get output buffer */ frame->nb_samples = s->samples; - if ((ret = ff_get_buffer(avctx, frame)) < 0) { + if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } diff --git a/libavcodec/wmadec.c b/libavcodec/wmadec.c index 6fbef08920..14a1521b1f 100644 --- a/libavcodec/wmadec.c +++ b/libavcodec/wmadec.c @@ -820,7 +820,7 @@ static int wma_decode_superframe(AVCodecContext *avctx, void *data, /* get output buffer */ frame->nb_samples = nb_frames * s->frame_len; - if ((ret = ff_get_buffer(avctx, frame)) < 0) { + if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } diff --git a/libavcodec/wmalosslessdec.c b/libavcodec/wmalosslessdec.c index 747ac37dc0..f9361baa7b 100644 --- a/libavcodec/wmalosslessdec.c +++ b/libavcodec/wmalosslessdec.c @@ -1015,7 +1015,7 @@ static int decode_frame(WmallDecodeCtx *s) int more_frames = 0, len = 0, i, ret; s->frame.nb_samples = s->samples_per_frame; - if ((ret = ff_get_buffer(s->avctx, &s->frame)) < 0) { + if ((ret = ff_get_buffer(s->avctx, &s->frame, 0)) < 0) { /* return an error if no frame could be decoded at all */ av_log(s->avctx, AV_LOG_ERROR, "not enough space for the output samples\n"); diff --git a/libavcodec/wmaprodec.c b/libavcodec/wmaprodec.c index 0954795f31..66f27c86f3 100644 --- a/libavcodec/wmaprodec.c +++ b/libavcodec/wmaprodec.c @@ -1362,7 +1362,7 @@ static int decode_frame(WMAProDecodeCtx *s, AVFrame *frame, int *got_frame_ptr) /* get output buffer */ frame->nb_samples = s->samples_per_frame; - if ((ret = ff_get_buffer(avctx, frame)) < 0) { + if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); s->packet_loss = 1; return 0; diff --git a/libavcodec/wmavoice.c b/libavcodec/wmavoice.c index f81e8e9403..f33def3b87 100644 --- a/libavcodec/wmavoice.c +++ b/libavcodec/wmavoice.c @@ -1801,7 +1801,7 @@ static int synth_superframe(AVCodecContext *ctx, AVFrame *frame, /* get output buffer */ frame->nb_samples = 480; - if ((res = ff_get_buffer(ctx, frame)) < 0) { + if ((res = ff_get_buffer(ctx, frame, 0)) < 0) { av_log(ctx, AV_LOG_ERROR, "get_buffer() failed\n"); return res; } diff --git a/libavcodec/wmv2dec.c b/libavcodec/wmv2dec.c index acce8c7c0f..f16b6de67e 100644 --- a/libavcodec/wmv2dec.c +++ b/libavcodec/wmv2dec.c @@ -31,7 +31,7 @@ static void parse_mb_skip(Wmv2Context * w){ int mb_x, mb_y; MpegEncContext * const s= &w->s; - uint32_t * const mb_type = s->current_picture_ptr->f.mb_type; + uint32_t * const mb_type = s->current_picture_ptr->mb_type; w->skip_type= get_bits(&s->gb, 2); switch(w->skip_type){ @@ -254,11 +254,11 @@ static int16_t *wmv2_pred_motion(Wmv2Context *w, int *px, int *py){ wrap = s->b8_stride; xy = s->block_index[0]; - mot_val = s->current_picture.f.motion_val[0][xy]; + mot_val = s->current_picture.motion_val[0][xy]; - A = s->current_picture.f.motion_val[0][xy - 1]; - B = s->current_picture.f.motion_val[0][xy - wrap]; - C = s->current_picture.f.motion_val[0][xy + 2 - wrap]; + A = s->current_picture.motion_val[0][xy - 1]; + B = s->current_picture.motion_val[0][xy - wrap]; + C = s->current_picture.motion_val[0][xy + 2 - wrap]; if(s->mb_x && !s->first_slice_line && !s->mspel && w->top_left_mv_flag) diff= FFMAX(FFABS(A[0] - B[0]), FFABS(A[1] - B[1])); @@ -339,7 +339,7 @@ int ff_wmv2_decode_mb(MpegEncContext *s, int16_t block[6][64]) if(w->j_type) return 0; if (s->pict_type == AV_PICTURE_TYPE_P) { - if (IS_SKIP(s->current_picture.f.mb_type[s->mb_y * s->mb_stride + s->mb_x])) { + if (IS_SKIP(s->current_picture.mb_type[s->mb_y * s->mb_stride + s->mb_x])) { /* skip mb */ s->mb_intra = 0; for(i=0;i<6;i++) diff --git a/libavcodec/wnv1.c b/libavcodec/wnv1.c index 0e727db418..2f9fc413b0 100644 --- a/libavcodec/wnv1.c +++ b/libavcodec/wnv1.c @@ -32,7 +32,6 @@ typedef struct WNV1Context { AVCodecContext *avctx; - AVFrame pic; int shift; GetBitContext gb; @@ -65,7 +64,7 @@ static int decode_frame(AVCodecContext *avctx, WNV1Context * const l = avctx->priv_data; const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; - AVFrame * const p = &l->pic; + AVFrame * const p = data; unsigned char *Y,*U,*V; int i, j, ret; int prev_y = 0, prev_u = 0, prev_v = 0; @@ -77,11 +76,7 @@ static int decode_frame(AVCodecContext *avctx, return AVERROR(ENOMEM); } - if (p->data[0]) - avctx->release_buffer(avctx, p); - - p->reference = 0; - if ((ret = ff_get_buffer(avctx, p)) < 0) { + if ((ret = ff_get_buffer(avctx, p, 0)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); av_free(rbuf); return ret; @@ -125,7 +120,6 @@ static int decode_frame(AVCodecContext *avctx, *got_frame = 1; - *(AVFrame*)data = l->pic; av_free(rbuf); return buf_size; @@ -148,24 +142,12 @@ static av_cold int decode_init(AVCodecContext *avctx) return 0; } -static av_cold int decode_end(AVCodecContext *avctx) -{ - WNV1Context * const l = avctx->priv_data; - AVFrame *pic = &l->pic; - - if (pic->data[0]) - avctx->release_buffer(avctx, pic); - - return 0; -} - AVCodec ff_wnv1_decoder = { .name = "wnv1", .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_WNV1, .priv_data_size = sizeof(WNV1Context), .init = decode_init, - .close = decode_end, .decode = decode_frame, .capabilities = CODEC_CAP_DR1, .long_name = NULL_IF_CONFIG_SMALL("Winnov WNV1"), diff --git a/libavcodec/ws-snd1.c b/libavcodec/ws-snd1.c index 62340c3bc5..14a93354ef 100644 --- a/libavcodec/ws-snd1.c +++ b/libavcodec/ws-snd1.c @@ -81,7 +81,7 @@ static int ws_snd_decode_frame(AVCodecContext *avctx, void *data, /* get output buffer */ frame->nb_samples = out_size; - if ((ret = ff_get_buffer(avctx, frame)) < 0) { + if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } diff --git a/libavcodec/xan.c b/libavcodec/xan.c index a1671e1cc5..ca2e8e0e2c 100644 --- a/libavcodec/xan.c +++ b/libavcodec/xan.c @@ -53,7 +53,6 @@ typedef struct XanContext { AVCodecContext *avctx; AVFrame last_frame; - AVFrame current_frame; const unsigned char *buf; int size; @@ -187,7 +186,7 @@ static void xan_unpack(unsigned char *dest, int dest_len, } } -static inline void xan_wc3_output_pixel_run(XanContext *s, +static inline void xan_wc3_output_pixel_run(XanContext *s, AVFrame *frame, const unsigned char *pixel_buffer, int x, int y, int pixel_count) { int stride; @@ -197,8 +196,8 @@ static inline void xan_wc3_output_pixel_run(XanContext *s, int width = s->avctx->width; unsigned char *palette_plane; - palette_plane = s->current_frame.data[0]; - stride = s->current_frame.linesize[0]; + palette_plane = frame->data[0]; + stride = frame->linesize[0]; line_inc = stride - width; index = y * stride + x; current_x = x; @@ -217,7 +216,8 @@ static inline void xan_wc3_output_pixel_run(XanContext *s, } } -static inline void xan_wc3_copy_pixel_run(XanContext *s, int x, int y, +static inline void xan_wc3_copy_pixel_run(XanContext *s, AVFrame *frame, + int x, int y, int pixel_count, int motion_x, int motion_y) { @@ -232,11 +232,11 @@ static inline void xan_wc3_copy_pixel_run(XanContext *s, int x, int y, x + motion_x < 0 || x + motion_x >= s->avctx->width) return; - palette_plane = s->current_frame.data[0]; + palette_plane = frame->data[0]; prev_palette_plane = s->last_frame.data[0]; if (!prev_palette_plane) prev_palette_plane = palette_plane; - stride = s->current_frame.linesize[0]; + stride = frame->linesize[0]; line_inc = stride - width; curframe_index = y * stride + x; curframe_x = x; @@ -268,7 +268,8 @@ static inline void xan_wc3_copy_pixel_run(XanContext *s, int x, int y, } } -static int xan_wc3_decode_frame(XanContext *s) { +static int xan_wc3_decode_frame(XanContext *s, AVFrame *frame) +{ int width = s->avctx->width; int height = s->avctx->height; @@ -383,12 +384,12 @@ static int xan_wc3_decode_frame(XanContext *s) { flag ^= 1; if (flag) { /* run of (size) pixels is unchanged from last frame */ - xan_wc3_copy_pixel_run(s, x, y, size, 0, 0); + xan_wc3_copy_pixel_run(s, frame, x, y, size, 0, 0); } else { /* output a run of pixels from imagedata_buffer */ if (imagedata_size < size) break; - xan_wc3_output_pixel_run(s, imagedata_buffer, x, y, size); + xan_wc3_output_pixel_run(s, frame, imagedata_buffer, x, y, size); imagedata_buffer += size; imagedata_size -= size; } @@ -399,7 +400,7 @@ static int xan_wc3_decode_frame(XanContext *s) { vector_segment++; /* copy a run of pixels from the previous frame */ - xan_wc3_copy_pixel_run(s, x, y, size, motion_x, motion_y); + xan_wc3_copy_pixel_run(s, frame, x, y, size, motion_x, motion_y); flag = 0; } @@ -499,6 +500,7 @@ static int xan_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { + AVFrame *frame = data; const uint8_t *buf = avpkt->data; int ret, buf_size = avpkt->size; XanContext *s = avctx->priv_data; @@ -563,33 +565,28 @@ static int xan_decode_frame(AVCodecContext *avctx, return AVERROR_INVALIDDATA; } - if ((ret = ff_get_buffer(avctx, &s->current_frame))) { + if ((ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF))) { av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } - s->current_frame.reference = 3; if (!s->frame_size) - s->frame_size = s->current_frame.linesize[0] * s->avctx->height; + s->frame_size = frame->linesize[0] * s->avctx->height; - memcpy(s->current_frame.data[1], + memcpy(frame->data[1], s->palettes + s->cur_palette * AVPALETTE_COUNT, AVPALETTE_SIZE); s->buf = ctx.buffer; s->size = buf_size; - if (xan_wc3_decode_frame(s) < 0) + if (xan_wc3_decode_frame(s, frame) < 0) return AVERROR_INVALIDDATA; - /* release the last frame if it is allocated */ - if (s->last_frame.data[0]) - avctx->release_buffer(avctx, &s->last_frame); + av_frame_unref(&s->last_frame); + if ((ret = av_frame_ref(&s->last_frame, frame)) < 0) + return ret; *got_frame = 1; - *(AVFrame*)data = s->current_frame; - - /* shuffle frames */ - FFSWAP(AVFrame, s->current_frame, s->last_frame); /* always report that the buffer was completely consumed */ return buf_size; @@ -599,11 +596,7 @@ static av_cold int xan_decode_end(AVCodecContext *avctx) { XanContext *s = avctx->priv_data; - /* release the frames */ - if (s->last_frame.data[0]) - avctx->release_buffer(avctx, &s->last_frame); - if (s->current_frame.data[0]) - avctx->release_buffer(avctx, &s->current_frame); + av_frame_unref(&s->last_frame); av_freep(&s->buffer1); av_freep(&s->buffer2); diff --git a/libavcodec/xl.c b/libavcodec/xl.c index ab45a5e35a..e7948a0057 100644 --- a/libavcodec/xl.c +++ b/libavcodec/xl.c @@ -29,11 +29,6 @@ #include "avcodec.h" #include "internal.h" -typedef struct VideoXLContext{ - AVCodecContext *avctx; - AVFrame pic; -} VideoXLContext; - static const int xl_table[32] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 12, 15, 20, 25, 34, 46, @@ -46,28 +41,23 @@ static int decode_frame(AVCodecContext *avctx, { const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; - VideoXLContext * const a = avctx->priv_data; - AVFrame * const p = &a->pic; + AVFrame * const p = data; uint8_t *Y, *U, *V; int i, j, ret; int stride; uint32_t val; int y0, y1, y2, y3 = 0, c0 = 0, c1 = 0; - if(p->data[0]) - avctx->release_buffer(avctx, p); - - p->reference = 0; - if ((ret = ff_get_buffer(avctx, p)) < 0){ + if ((ret = ff_get_buffer(avctx, p, 0)) < 0){ av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } p->pict_type= AV_PICTURE_TYPE_I; p->key_frame= 1; - Y = a->pic.data[0]; - U = a->pic.data[1]; - V = a->pic.data[2]; + Y = p->data[0]; + U = p->data[1]; + V = p->data[2]; stride = avctx->width - 4; @@ -117,42 +107,27 @@ static int decode_frame(AVCodecContext *avctx, } buf += avctx->width + 4; - Y += a->pic.linesize[0]; - U += a->pic.linesize[1]; - V += a->pic.linesize[2]; + Y += p->linesize[0]; + U += p->linesize[1]; + V += p->linesize[2]; } *got_frame = 1; - *(AVFrame*)data = a->pic; return buf_size; } static av_cold int decode_init(AVCodecContext *avctx){ -// VideoXLContext * const a = avctx->priv_data; - avctx->pix_fmt= AV_PIX_FMT_YUV411P; return 0; } -static av_cold int decode_end(AVCodecContext *avctx){ - VideoXLContext * const a = avctx->priv_data; - AVFrame *pic = &a->pic; - - if (pic->data[0]) - avctx->release_buffer(avctx, pic); - - return 0; -} - AVCodec ff_xl_decoder = { .name = "xl", .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_VIXL, - .priv_data_size = sizeof(VideoXLContext), .init = decode_init, - .close = decode_end, .decode = decode_frame, .capabilities = CODEC_CAP_DR1, .long_name = NULL_IF_CONFIG_SMALL("Miro VideoXL"), diff --git a/libavcodec/xwddec.c b/libavcodec/xwddec.c index 274e4fa103..23f9c01d60 100644 --- a/libavcodec/xwddec.c +++ b/libavcodec/xwddec.c @@ -26,19 +26,10 @@ #include "internal.h" #include "xwd.h" -static av_cold int xwd_decode_init(AVCodecContext *avctx) -{ - avctx->coded_frame = avcodec_alloc_frame(); - if (!avctx->coded_frame) - return AVERROR(ENOMEM); - - return 0; -} - static int xwd_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { - AVFrame *p = avctx->coded_frame; + AVFrame *p = data; const uint8_t *buf = avpkt->data; int i, ret, buf_size = avpkt->size; uint32_t version, header_size, vclass, ncolors; @@ -205,11 +196,7 @@ static int xwd_decode_frame(AVCodecContext *avctx, void *data, return AVERROR_PATCHWELCOME; } - if (p->data[0]) - avctx->release_buffer(avctx, p); - - p->reference = 0; - if ((ret = ff_get_buffer(avctx, p)) < 0) { + if ((ret = ff_get_buffer(avctx, p, 0)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } @@ -243,27 +230,14 @@ static int xwd_decode_frame(AVCodecContext *avctx, void *data, } *got_frame = 1; - *(AVFrame *)data = *p; return buf_size; } -static av_cold int xwd_decode_close(AVCodecContext *avctx) -{ - if (avctx->coded_frame->data[0]) - avctx->release_buffer(avctx, avctx->coded_frame); - - av_freep(&avctx->coded_frame); - - return 0; -} - AVCodec ff_xwd_decoder = { .name = "xwd", .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_XWD, - .init = xwd_decode_init, - .close = xwd_decode_close, .decode = xwd_decode_frame, .capabilities = CODEC_CAP_DR1, .long_name = NULL_IF_CONFIG_SMALL("XWD (X Window Dump) image"), diff --git a/libavcodec/xxan.c b/libavcodec/xxan.c index 31f475512a..47ab54a7f9 100644 --- a/libavcodec/xxan.c +++ b/libavcodec/xxan.c @@ -26,6 +26,7 @@ #include "bytestream.h" #define BITSTREAM_READER_LE #include "get_bits.h" +#include "internal.h" typedef struct XanContext { AVCodecContext *avctx; @@ -379,11 +380,7 @@ static int xan_decode_frame(AVCodecContext *avctx, int ftype; int ret; - s->pic.reference = 1; - s->pic.buffer_hints = FF_BUFFER_HINTS_VALID | - FF_BUFFER_HINTS_PRESERVE | - FF_BUFFER_HINTS_REUSABLE; - if ((ret = avctx->reget_buffer(avctx, &s->pic))) { + if ((ret = ff_reget_buffer(avctx, &s->pic))) { av_log(s->avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); return ret; } @@ -404,8 +401,10 @@ static int xan_decode_frame(AVCodecContext *avctx, if (ret) return ret; + if ((ret = av_frame_ref(data, &s->pic)) < 0) + return ret; + *got_frame = 1; - *(AVFrame*)data = s->pic; return avpkt->size; } @@ -414,8 +413,7 @@ static av_cold int xan_decode_end(AVCodecContext *avctx) { XanContext *s = avctx->priv_data; - if (s->pic.data[0]) - avctx->release_buffer(avctx, &s->pic); + av_frame_unref(&s->pic); av_freep(&s->y_buffer); av_freep(&s->scratch_buffer); diff --git a/libavcodec/yop.c b/libavcodec/yop.c index fd7f090839..3a760c5345 100644 --- a/libavcodec/yop.c +++ b/libavcodec/yop.c @@ -30,7 +30,6 @@ #include "internal.h" typedef struct YopDecContext { - AVFrame frame; AVCodecContext *avctx; int num_pal_colors; @@ -111,30 +110,22 @@ static av_cold int yop_decode_init(AVCodecContext *avctx) return 0; } -static av_cold int yop_decode_close(AVCodecContext *avctx) -{ - YopDecContext *s = avctx->priv_data; - if (s->frame.data[0]) - avctx->release_buffer(avctx, &s->frame); - return 0; -} - /** * Paint a macroblock using the pattern in paint_lut. * @param s codec context * @param tag the tag that was in the nibble */ -static int yop_paint_block(YopDecContext *s, int tag) +static int yop_paint_block(YopDecContext *s, int linesize, int tag) { if (s->src_end - s->srcptr < paint_lut[tag][3]) { av_log(s->avctx, AV_LOG_ERROR, "Packet too small.\n"); return AVERROR_INVALIDDATA; } - s->dstptr[0] = s->srcptr[0]; - s->dstptr[1] = s->srcptr[paint_lut[tag][0]]; - s->dstptr[s->frame.linesize[0]] = s->srcptr[paint_lut[tag][1]]; - s->dstptr[s->frame.linesize[0] + 1] = s->srcptr[paint_lut[tag][2]]; + s->dstptr[0] = s->srcptr[0]; + s->dstptr[1] = s->srcptr[paint_lut[tag][0]]; + s->dstptr[linesize] = s->srcptr[paint_lut[tag][1]]; + s->dstptr[linesize + 1] = s->srcptr[paint_lut[tag][2]]; // The number of src bytes consumed is in the last part of the lut entry. s->srcptr += paint_lut[tag][3]; @@ -145,23 +136,23 @@ static int yop_paint_block(YopDecContext *s, int tag) * Copy a previously painted macroblock to the current_block. * @param copy_tag the tag that was in the nibble */ -static int yop_copy_previous_block(YopDecContext *s, int copy_tag) +static int yop_copy_previous_block(YopDecContext *s, int linesize, int copy_tag) { uint8_t *bufptr; // Calculate position for the copy source bufptr = s->dstptr + motion_vector[copy_tag][0] + - s->frame.linesize[0] * motion_vector[copy_tag][1]; + linesize * motion_vector[copy_tag][1]; if (bufptr < s->dstbuf) { av_log(s->avctx, AV_LOG_ERROR, "YOP: cannot decode, file probably corrupt\n"); return AVERROR_INVALIDDATA; } - s->dstptr[0] = bufptr[0]; - s->dstptr[1] = bufptr[1]; - s->dstptr[s->frame.linesize[0]] = bufptr[s->frame.linesize[0]]; - s->dstptr[s->frame.linesize[0] + 1] = bufptr[s->frame.linesize[0] + 1]; + s->dstptr[0] = bufptr[0]; + s->dstptr[1] = bufptr[1]; + s->dstptr[linesize] = bufptr[linesize]; + s->dstptr[linesize + 1] = bufptr[linesize + 1]; return 0; } @@ -188,6 +179,7 @@ static int yop_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { YopDecContext *s = avctx->priv_data; + AVFrame *frame = data; int tag, firstcolor, is_odd_frame; int ret, i, x, y; uint32_t *palette; @@ -197,34 +189,31 @@ static int yop_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, return AVERROR_INVALIDDATA; } - if (s->frame.data[0]) - avctx->release_buffer(avctx, &s->frame); - - ret = ff_get_buffer(avctx, &s->frame); + ret = ff_get_buffer(avctx, frame, 0); if (ret < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } if (!avctx->frame_number) - memset(s->frame.data[1], 0, AVPALETTE_SIZE); + memset(frame->data[1], 0, AVPALETTE_SIZE); - s->dstbuf = s->frame.data[0]; - s->dstptr = s->frame.data[0]; + s->dstbuf = frame->data[0]; + s->dstptr = frame->data[0]; s->srcptr = avpkt->data + 4; s->src_end = avpkt->data + avpkt->size; s->low_nibble = NULL; is_odd_frame = avpkt->data[0]; firstcolor = s->first_color[is_odd_frame]; - palette = (uint32_t *)s->frame.data[1]; + palette = (uint32_t *)frame->data[1]; for (i = 0; i < s->num_pal_colors; i++, s->srcptr += 3) palette[i + firstcolor] = (s->srcptr[0] << 18) | (s->srcptr[1] << 10) | (s->srcptr[2] << 2); - s->frame.palette_has_changed = 1; + frame->palette_has_changed = 1; for (y = 0; y < avctx->height; y += 2) { for (x = 0; x < avctx->width; x += 2) { @@ -236,24 +225,21 @@ static int yop_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, tag = yop_get_next_nibble(s); if (tag != 0xf) { - ret = yop_paint_block(s, tag); + ret = yop_paint_block(s, frame->linesize[0], tag); if (ret < 0) return ret; } else { tag = yop_get_next_nibble(s); - ret = yop_copy_previous_block(s, tag); - if (ret < 0) { - avctx->release_buffer(avctx, &s->frame); + ret = yop_copy_previous_block(s, frame->linesize[0], tag); + if (ret < 0) return ret; - } } s->dstptr += 2; } - s->dstptr += 2*s->frame.linesize[0] - x; + s->dstptr += 2*frame->linesize[0] - x; } *got_frame = 1; - *(AVFrame *) data = s->frame; return avpkt->size; } @@ -263,7 +249,6 @@ AVCodec ff_yop_decoder = { .id = AV_CODEC_ID_YOP, .priv_data_size = sizeof(YopDecContext), .init = yop_decode_init, - .close = yop_decode_close, .decode = yop_decode_frame, .long_name = NULL_IF_CONFIG_SMALL("Psygnosis YOP Video"), .capabilities = CODEC_CAP_DR1, diff --git a/libavcodec/zerocodec.c b/libavcodec/zerocodec.c index 8122cca3b2..e503aa7689 100644 --- a/libavcodec/zerocodec.c +++ b/libavcodec/zerocodec.c @@ -31,14 +31,12 @@ static int zerocodec_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { ZeroCodecContext *zc = avctx->priv_data; - AVFrame *pic = avctx->coded_frame; + AVFrame *pic = data; AVFrame *prev_pic = &zc->previous_frame; z_stream *zstream = &zc->zstream; uint8_t *prev = prev_pic->data[0]; uint8_t *dst; - int i, j, zret; - - pic->reference = 3; + int i, j, zret, ret; if (avpkt->flags & AV_PKT_FLAG_KEY) { pic->key_frame = 1; @@ -61,7 +59,7 @@ static int zerocodec_decode_frame(AVCodecContext *avctx, void *data, return AVERROR_INVALIDDATA; } - if (ff_get_buffer(avctx, pic) < 0) { + if (ff_get_buffer(avctx, pic, AV_GET_BUFFER_FLAG_REF) < 0) { av_log(avctx, AV_LOG_ERROR, "Could not allocate buffer.\n"); return AVERROR(ENOMEM); } @@ -82,7 +80,6 @@ static int zerocodec_decode_frame(AVCodecContext *avctx, void *data, zret = inflate(zstream, Z_SYNC_FLUSH); if (zret != Z_OK && zret != Z_STREAM_END) { - avctx->release_buffer(avctx, pic); av_log(avctx, AV_LOG_ERROR, "Inflate failed with return code: %d.\n", zret); return AVERROR_INVALIDDATA; @@ -96,16 +93,11 @@ static int zerocodec_decode_frame(AVCodecContext *avctx, void *data, dst -= pic->linesize[0]; } - /* Release the previous buffer if need be */ - if (prev_pic->data[0]) - avctx->release_buffer(avctx, prev_pic); + av_frame_unref(&zc->previous_frame); + if ((ret = av_frame_ref(&zc->previous_frame, pic)) < 0) + return ret; *got_frame = 1; - *(AVFrame *)data = *pic; - - /* Store the previous frame for use later. - * FFSWAP ensures that e.g. pic->data is NULLed. */ - FFSWAP(AVFrame, *pic, *prev_pic); return avpkt->size; } @@ -113,16 +105,11 @@ static int zerocodec_decode_frame(AVCodecContext *avctx, void *data, static av_cold int zerocodec_decode_close(AVCodecContext *avctx) { ZeroCodecContext *zc = avctx->priv_data; - AVFrame *prev_pic = &zc->previous_frame; + + av_frame_unref(&zc->previous_frame); inflateEnd(&zc->zstream); - /* Release last frame */ - if (prev_pic->data[0]) - avctx->release_buffer(avctx, prev_pic); - - av_freep(&avctx->coded_frame); - return 0; } @@ -145,13 +132,6 @@ static av_cold int zerocodec_decode_init(AVCodecContext *avctx) return AVERROR(ENOMEM); } - avctx->coded_frame = avcodec_alloc_frame(); - if (!avctx->coded_frame) { - av_log(avctx, AV_LOG_ERROR, "Could not allocate frame buffer.\n"); - zerocodec_decode_close(avctx); - return AVERROR(ENOMEM); - } - return 0; } diff --git a/libavcodec/zmbv.c b/libavcodec/zmbv.c index 5d4254aec0..8cf6a0cb5b 100644 --- a/libavcodec/zmbv.c +++ b/libavcodec/zmbv.c @@ -54,7 +54,6 @@ enum ZmbvFormat { */ typedef struct ZmbvContext { AVCodecContext *avctx; - AVFrame pic; int bpp; unsigned int decomp_size; @@ -400,6 +399,7 @@ static int zmbv_decode_intra(ZmbvContext *c) static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { + AVFrame *frame = data; const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; ZmbvContext * const c = avctx->priv_data; @@ -408,12 +408,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac int hi_ver, lo_ver, ret; uint8_t *tmp; - if (c->pic.data[0]) - avctx->release_buffer(avctx, &c->pic); - - c->pic.reference = 1; - c->pic.buffer_hints = FF_BUFFER_HINTS_VALID; - if ((ret = ff_get_buffer(avctx, &c->pic)) < 0) { + if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } @@ -524,12 +519,12 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac c->decomp_len = c->zstream.total_out; } if (c->flags & ZMBV_KEYFRAME) { - c->pic.key_frame = 1; - c->pic.pict_type = AV_PICTURE_TYPE_I; + frame->key_frame = 1; + frame->pict_type = AV_PICTURE_TYPE_I; c->decode_intra(c); } else { - c->pic.key_frame = 0; - c->pic.pict_type = AV_PICTURE_TYPE_P; + frame->key_frame = 0; + frame->pict_type = AV_PICTURE_TYPE_P; if (c->decomp_len) c->decode_xor(c); } @@ -539,7 +534,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac uint8_t *out, *src; int i, j; - out = c->pic.data[0]; + out = frame->data[0]; src = c->cur; switch (c->fmt) { case ZMBV_FMT_8BPP: @@ -550,7 +545,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac out[i * 3 + 2] = c->pal[(*src) * 3 + 2]; src++; } - out += c->pic.linesize[0]; + out += frame->linesize[0]; } break; case ZMBV_FMT_15BPP: @@ -562,7 +557,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac out[i * 3 + 1] = (tmp & 0x03E0) >> 2; out[i * 3 + 2] = (tmp & 0x001F) << 3; } - out += c->pic.linesize[0]; + out += frame->linesize[0]; } break; case ZMBV_FMT_16BPP: @@ -574,7 +569,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac out[i * 3 + 1] = (tmp & 0x07E0) >> 3; out[i * 3 + 2] = (tmp & 0x001F) << 3; } - out += c->pic.linesize[0]; + out += frame->linesize[0]; } break; #ifdef ZMBV_ENABLE_24BPP @@ -582,7 +577,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac for (j = 0; j < c->height; j++) { memcpy(out, src, c->width * 3); src += c->width * 3; - out += c->pic.linesize[0]; + out += frame->linesize[0]; } break; #endif //ZMBV_ENABLE_24BPP @@ -593,7 +588,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac src += 4; AV_WB24(out+(i*3), tmp); } - out += c->pic.linesize[0]; + out += frame->linesize[0]; } break; default: @@ -602,7 +597,6 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac FFSWAP(uint8_t *, c->cur, c->prev); } *got_frame = 1; - *(AVFrame*)data = c->pic; /* always report that the buffer was completely consumed */ return buf_size; @@ -653,8 +647,6 @@ static av_cold int decode_end(AVCodecContext *avctx) av_freep(&c->decomp_buf); - if (c->pic.data[0]) - avctx->release_buffer(avctx, &c->pic); inflateEnd(&c->zstream); av_freep(&c->cur); av_freep(&c->prev);