[libav-devel] [PATCH] qsv: enforcing continuous memory layout

maxim_d33 maxim.d33 at gmail.com
Sat Jul 28 10:53:54 CEST 2018


---
 libavcodec/qsvenc.c | 34 ++++++++++++++++++++++++----------
 1 file changed, 24 insertions(+), 10 deletions(-)

diff --git a/libavcodec/qsvenc.c b/libavcodec/qsvenc.c
index e349a075f..9fb1ae01b 100644
--- a/libavcodec/qsvenc.c
+++ b/libavcodec/qsvenc.c
@@ -1061,6 +1061,7 @@ static int submit_frame(QSVEncContext *q, const AVFrame *frame,
 {
     QSVFrame *qf;
     int ret;
+    AVFrame* aligned_frame;
 
     ret = get_free_frame(q, &qf);
     if (ret < 0)
@@ -1081,22 +1082,35 @@ static int submit_frame(QSVEncContext *q, const AVFrame *frame,
             qf->surface.Data.MemId = &q->frames_ctx.mids[ret];
         }
     } else {
-        /* make a copy if the input is not padded as libmfx requires */
-        if (frame->height & 31 || frame->linesize[0] & (q->width_align - 1)) {
-            qf->frame->height = FFALIGN(frame->height, q->height_align);
-            qf->frame->width  = FFALIGN(frame->width, q->width_align);
-
-            ret = ff_get_buffer(q->avctx, qf->frame, AV_GET_BUFFER_FLAG_REF);
+        /* make a copy if
+           - the input is not padded
+           - allocations are not continious for data[0]/data[1]
+           required by libmfx */
+          if ((frame->data[1] - frame->data[0] != frame->linesize[0] * FFALIGN(frame->height, q->height_align)) ||
+            (frame->height & 31 || frame->linesize[0] & (q->width_align - 1))) {
+            aligned_frame = av_frame_alloc();
+            if (!aligned_frame)
+                return AVERROR(ENOMEM);
+
+            aligned_frame->format = frame->format;
+            aligned_frame->height = FFALIGN(frame->height, q->height_align);
+            aligned_frame->width  = FFALIGN(frame->width, q->width_align);
+
+            ret = av_frame_get_buffer(aligned_frame,q->width_align);
             if (ret < 0)
                 return ret;
 
-            qf->frame->height = frame->height;
-            qf->frame->width  = frame->width;
-            ret = av_frame_copy(qf->frame, frame);
+            aligned_frame->height = frame->height;
+            aligned_frame->width  = frame->width;
+
+            ret = av_frame_copy(aligned_frame, frame);
             if (ret < 0) {
-                av_frame_unref(qf->frame);
+                av_frame_unref(aligned_frame);
                 return ret;
             }
+
+            av_frame_free(&qf->frame);
+            qf->frame = aligned_frame;
         } else {
             ret = av_frame_ref(qf->frame, frame);
             if (ret < 0)
-- 
2.14.2



More information about the libav-devel mailing list