Browse code

qsv{dec,enc}: use a struct as a memory id with internal memory allocator

This will allow implementing the allocator more fully, which is needed
by the HEVC encoder plugin with video memory input.

Signed-off-by: Maxym Dmytrychenko <maxym.dmytrychenko@intel.com>

Anton Khirnov authored on 2016/08/10 15:29:23
Showing 4 changed files
... ...
@@ -144,6 +144,17 @@ int ff_qsv_map_pixfmt(enum AVPixelFormat format, uint32_t *fourcc)
144 144
     }
145 145
 }
146 146
 
147
+int ff_qsv_find_surface_idx(QSVFramesContext *ctx, QSVFrame *frame)
148
+{
149
+    int i;
150
+    for (i = 0; i < ctx->nb_mids; i++) {
151
+        QSVMid *mid = &ctx->mids[i];
152
+        if (mid->handle == frame->surface.Data.MemId)
153
+            return i;
154
+    }
155
+    return AVERROR_BUG;
156
+}
157
+
147 158
 static int qsv_load_plugins(mfxSession session, const char *load_plugins,
148 159
                             void *logctx)
149 160
 {
... ...
@@ -244,6 +255,7 @@ static mfxStatus qsv_frame_alloc(mfxHDL pthis, mfxFrameAllocRequest *req,
244 244
     QSVFramesContext *ctx = pthis;
245 245
     mfxFrameInfo      *i  = &req->Info;
246 246
     mfxFrameInfo      *i1 = &ctx->info;
247
+    int j;
247 248
 
248 249
     if (!(req->Type & MFX_MEMTYPE_VIDEO_MEMORY_DECODER_TARGET) ||
249 250
         !(req->Type & (MFX_MEMTYPE_FROM_DECODE | MFX_MEMTYPE_FROM_ENCODE)) ||
... ...
@@ -258,7 +270,13 @@ static mfxStatus qsv_frame_alloc(mfxHDL pthis, mfxFrameAllocRequest *req,
258 258
         return MFX_ERR_UNSUPPORTED;
259 259
     }
260 260
 
261
-    resp->mids           = ctx->mids;
261
+    resp->mids = av_mallocz_array(ctx->nb_mids, sizeof(*resp->mids));
262
+    if (!resp->mids)
263
+        return MFX_ERR_MEMORY_ALLOC;
264
+
265
+    for (j = 0; j < ctx->nb_mids; j++)
266
+        resp->mids[j] = &ctx->mids[j];
267
+
262 268
     resp->NumFrameActual = ctx->nb_mids;
263 269
 
264 270
     return MFX_ERR_NONE;
... ...
@@ -266,6 +284,7 @@ static mfxStatus qsv_frame_alloc(mfxHDL pthis, mfxFrameAllocRequest *req,
266 266
 
267 267
 static mfxStatus qsv_frame_free(mfxHDL pthis, mfxFrameAllocResponse *resp)
268 268
 {
269
+    av_freep(&resp->mids);
269 270
     return MFX_ERR_NONE;
270 271
 }
271 272
 
... ...
@@ -281,7 +300,8 @@ static mfxStatus qsv_frame_unlock(mfxHDL pthis, mfxMemId mid, mfxFrameData *ptr)
281 281
 
282 282
 static mfxStatus qsv_frame_get_hdl(mfxHDL pthis, mfxMemId mid, mfxHDL *hdl)
283 283
 {
284
-    *hdl = mid;
284
+    QSVMid *qsv_mid = (QSVMid*)mid;
285
+    *hdl = qsv_mid->handle;
285 286
     return MFX_ERR_NONE;
286 287
 }
287 288
 
... ...
@@ -365,7 +385,7 @@ int ff_qsv_init_session_hwcontext(AVCodecContext *avctx, mfxSession *psession,
365 365
         qsv_frames_ctx->info    = frames_hwctx->surfaces[0].Info;
366 366
         qsv_frames_ctx->nb_mids = frames_hwctx->nb_surfaces;
367 367
         for (i = 0; i < frames_hwctx->nb_surfaces; i++)
368
-            qsv_frames_ctx->mids[i] = frames_hwctx->surfaces[i].Data.MemId;
368
+            qsv_frames_ctx->mids[i].handle = frames_hwctx->surfaces[i].Data.MemId;
369 369
 
370 370
         err = MFXVideoCORE_SetFrameAllocator(session, &frame_allocator);
371 371
         if (err != MFX_ERR_NONE)
... ...
@@ -36,6 +36,10 @@
36 36
     (MFX_VERSION_MAJOR > (MAJOR) ||         \
37 37
      MFX_VERSION_MAJOR == (MAJOR) && MFX_VERSION_MINOR >= (MINOR))
38 38
 
39
+typedef struct QSVMid {
40
+    mfxHDL handle;
41
+} QSVMid;
42
+
39 43
 typedef struct QSVFrame {
40 44
     AVFrame *frame;
41 45
     mfxFrameSurface1 surface;
... ...
@@ -49,8 +53,8 @@ typedef struct QSVFrame {
49 49
 typedef struct QSVFramesContext {
50 50
     AVBufferRef *hw_frames_ctx;
51 51
     mfxFrameInfo info;
52
-    mfxMemId *mids;
53
-    int    nb_mids;
52
+    QSVMid *mids;
53
+    int  nb_mids;
54 54
 } QSVFramesContext;
55 55
 
56 56
 /**
... ...
@@ -75,4 +79,6 @@ int ff_qsv_init_session_hwcontext(AVCodecContext *avctx, mfxSession *session,
75 75
                                   QSVFramesContext *qsv_frames_ctx,
76 76
                                   const char *load_plugins, int opaque);
77 77
 
78
+int ff_qsv_find_surface_idx(QSVFramesContext *ctx, QSVFrame *frame);
79
+
78 80
 #endif /* AVCODEC_QSV_INTERNAL_H */
... ...
@@ -188,6 +188,14 @@ static int alloc_frame(AVCodecContext *avctx, QSVContext *q, QSVFrame *frame)
188 188
         frame->surface.Data.UV       = frame->frame->data[1];
189 189
     }
190 190
 
191
+    if (q->frames_ctx.mids) {
192
+        ret = ff_qsv_find_surface_idx(&q->frames_ctx, frame);
193
+        if (ret < 0)
194
+            return ret;
195
+
196
+        frame->surface.Data.MemId = &q->frames_ctx.mids[ret];
197
+    }
198
+
191 199
     frame->used = 1;
192 200
 
193 201
     return 0;
... ...
@@ -872,6 +872,14 @@ static int submit_frame(QSVEncContext *q, const AVFrame *frame,
872 872
             return ret;
873 873
 
874 874
         qf->surface = *(mfxFrameSurface1*)qf->frame->data[3];
875
+
876
+        if (q->frames_ctx.mids) {
877
+            ret = ff_qsv_find_surface_idx(&q->frames_ctx, qf);
878
+            if (ret < 0)
879
+                return ret;
880
+
881
+            qf->surface.Data.MemId = &q->frames_ctx.mids[ret];
882
+        }
875 883
     } else {
876 884
         /* make a copy if the input is not padded as libmfx requires */
877 885
         if (frame->height & 31 || frame->linesize[0] & (q->width_align - 1)) {