From 681f74b224e16a4df7f8c4e31a9be56975d57e10 Mon Sep 17 00:00:00 2001
From: CrystalP <CrystalP@xbmc.org>
Date: Mon, 10 Oct 2011 19:42:50 -0400
Subject: [PATCH 19/24] dxva-mpeg2 speed up slice allocation

The number of slices is not very likely to change from frame to frame, so
at the beginning of a new frame, allocate memory for the amount of slices of
the previous frame. Saves a lot of reallocation, for some TV capture samples
there are over 200 slices.

There wasn't anywhere really appropriate to store last_slice_count (needs to
live from first frame to last frame), so this is likely to cause discussion to
merge upstream.
Adding members to dxva_context breaks ABI, which we don't care too much about
since on Windows we don't support external ffmpeg.
dxva mpeg2 code also has access to MpegEncContext, but adding there would
likely break ABI as well.
---
 libavcodec/dxva2.h       |    1 +
 libavcodec/dxva2_mpeg2.c |   12 ++++++++++++
 2 files changed, 13 insertions(+)

diff --git a/libavcodec/dxva2.h b/libavcodec/dxva2.h
index fc99560..16a6994 100644
--- a/libavcodec/dxva2.h
+++ b/libavcodec/dxva2.h
@@ -66,6 +66,7 @@ struct dxva_context {
      * Private to the FFmpeg AVHWAccel implementation
      */
     unsigned report_id;
+    unsigned last_slice_count;
 };
 
 #endif /* AVCODEC_DXVA_H */
diff --git a/libavcodec/dxva2_mpeg2.c b/libavcodec/dxva2_mpeg2.c
index 8ba83b6..90507f9 100644
--- a/libavcodec/dxva2_mpeg2.c
+++ b/libavcodec/dxva2_mpeg2.c
@@ -224,6 +224,16 @@ static int start_frame(AVCodecContext *avctx,
     ctx_pic->slice_alloc    = 0;
     ctx_pic->bitstream_size = 0;
     ctx_pic->bitstream      = NULL;
+
+    if (ctx->last_slice_count > 0)
+    {
+        ctx_pic->slice = av_fast_realloc(NULL,
+                                         &ctx_pic->slice_alloc,
+                                         ctx->last_slice_count * sizeof(DXVA_SliceInfo));
+        if (!ctx_pic->slice)
+            return -1;
+    }
+
     return 0;
 }
 
@@ -258,6 +268,7 @@ static int end_frame(AVCodecContext *avctx)
     struct MpegEncContext *s = avctx->priv_data;
     struct dxva2_picture_context *ctx_pic =
         s->current_picture_ptr->f.hwaccel_picture_private;
+    struct dxva_context *ctx = avctx->hwaccel_context;
 
     if (ctx_pic->slice_count <= 0 || ctx_pic->bitstream_size <= 0)
         return -1;
@@ -266,6 +277,7 @@ static int end_frame(AVCodecContext *avctx)
                                      &ctx_pic->qm, sizeof(ctx_pic->qm),
                                      commit_bitstream_and_slice_buffer);
     av_freep(ctx_pic->slice);
+    ctx->last_slice_count = ctx_pic->slice_count;
 }
 
 AVHWAccel ff_mpeg2_dxva2_hwaccel = {
-- 
1.7.9.4

