summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUoti Urpala <uau@mplayer2.org>2012-04-15 17:48:12 +0300
committerUoti Urpala <uau@mplayer2.org>2012-04-15 17:48:12 +0300
commitaadf1002f8aa3a5813fd13ad18b8907b82068811 (patch)
treea855c25f6a614b5b6d92946598ff952f18cd1128
parentb711624ef350d1e971f5fcc57eb4af9f74233d2a (diff)
downloadmpv-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.c28
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;