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>
... | ... |
@@ -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)) { |