diff options
author | Uoti Urpala <uau@mplayer2.org> | 2012-04-15 17:48:12 +0300 |
---|---|---|
committer | Uoti Urpala <uau@mplayer2.org> | 2012-04-15 17:48:12 +0300 |
commit | aadf1002f8aa3a5813fd13ad18b8907b82068811 (patch) | |
tree | a855c25f6a614b5b6d92946598ff952f18cd1128 | |
parent | b711624ef350d1e971f5fcc57eb4af9f74233d2a (diff) | |
download | mpv-aadf1002f8aa3a5813fd13ad18b8907b82068811.tar.bz2 mpv-aadf1002f8aa3a5813fd13ad18b8907b82068811.tar.xz |
screenshot: fix dependency on sizeof(AVFrame)
The AVFrame data structure may be extended at the end in new
binary-compatible libavcodec versions. Therefore applications should
not depend on the size of the structure. But screenshot.c declared an
"AVFrame pic;" on stack. Change the code to allocate an AVFrame with
avcodec_alloc_frame() instead. The frame is now stored in struct
screenshot_ctx (rather than reallocated each time).
-rw-r--r-- | screenshot.c | 28 |
1 files changed, 21 insertions, 7 deletions
diff --git a/screenshot.c b/screenshot.c index af1c5c1da2..4a9a6c435a 100644 --- a/screenshot.c +++ b/screenshot.c @@ -20,6 +20,7 @@ #include <stdlib.h> #include <string.h> #include <inttypes.h> +#include <assert.h> #include <libswscale/swscale.h> #include <libavcodec/avcodec.h> @@ -43,6 +44,7 @@ #include "libvo/csputils.h" typedef struct screenshot_ctx { + AVFrame *pic; int full_window; int each_frame; int using_vf_screenshot; @@ -51,10 +53,22 @@ typedef struct screenshot_ctx { char fname[102]; } screenshot_ctx; +static int destroy_ctx(void *ptr) +{ + struct screenshot_ctx *ctx = ptr; + av_free(ctx->pic); + return 0; +} + static screenshot_ctx *screenshot_get_ctx(MPContext *mpctx) { - if (!mpctx->screenshot_ctx) - mpctx->screenshot_ctx = talloc_zero(mpctx, screenshot_ctx); + if (!mpctx->screenshot_ctx) { + struct screenshot_ctx *ctx = talloc_zero(mpctx, screenshot_ctx); + talloc_set_destructor(ctx, destroy_ctx); + ctx->pic = avcodec_alloc_frame(); + assert(ctx->pic); + mpctx->screenshot_ctx = ctx; + } return mpctx->screenshot_ctx; } @@ -91,13 +105,13 @@ static int write_png(screenshot_ctx *ctx, struct mp_image *image) if (!outbuffer) goto error_exit; - AVFrame pic; - avcodec_get_frame_defaults(&pic); + AVFrame *pic = ctx->pic; + avcodec_get_frame_defaults(pic); for (int n = 0; n < 4; n++) { - pic.data[n] = image->planes[n]; - pic.linesize[n] = image->stride[n]; + pic->data[n] = image->planes[n]; + pic->linesize[n] = image->stride[n]; } - int size = avcodec_encode_video(avctx, outbuffer, outbuffer_size, &pic); + int size = avcodec_encode_video(avctx, outbuffer, outbuffer_size, pic); if (size < 1) goto error_exit; |