| @@ -134,7 +134,7 @@ static int init_video_param(AVCodecContext *avctx, QSVEncContext *q) · 133 unmodified lines |
| 134 | 134 | q->extco.CAVLC = avctx->coder_type == FF_CODER_TYPE_VLC ? |
| 135 | 135 | MFX_CODINGOPTION_ON : MFX_CODINGOPTION_UNKNOWN; |
| 136 | 136 | |
| 137 | | − q->extparam_internal[0] = (mfxExtBuffer *)&q->extco; |
| 137 | + q->extparam_internal[q->nb_extparam_internal++] = (mfxExtBuffer *)&q->extco; |
| 138 | 138 | } |
| 139 | 139 | |
| 140 | 140 | return 0; |
| @@ -187,8 +187,46 @@ static int qsv_retrieve_enc_params(AVCodecContext *avctx, QSVEncContext *q) · 46 unmodified lines |
| 187 | 187 | return 0; |
| 188 | 188 | } |
| 189 | 189 | |
| 190 | +static int qsv_init_opaque_alloc(AVCodecContext *avctx, QSVEncContext *q) |
| 191 | +{ |
| 192 | + AVQSVContext *qsv = avctx->hwaccel_context; |
| 193 | + mfxFrameSurface1 *surfaces; |
| 194 | + int nb_surfaces, i; |
| 195 | + |
| 196 | + nb_surfaces = qsv->nb_opaque_surfaces + q->req.NumFrameSuggested + q->async_depth; |
| 197 | + |
| 198 | + q->opaque_alloc_buf = av_buffer_allocz(sizeof(*surfaces) * nb_surfaces); |
| 199 | + if (!q->opaque_alloc_buf) |
| 200 | + return AVERROR(ENOMEM); |
| 201 | + |
| 202 | + q->opaque_surfaces = av_malloc_array(nb_surfaces, sizeof(*q->opaque_surfaces)); |
| 203 | + if (!q->opaque_surfaces) |
| 204 | + return AVERROR(ENOMEM); |
| 205 | + |
| 206 | + surfaces = (mfxFrameSurface1*)q->opaque_alloc_buf->data; |
| 207 | + for (i = 0; i < nb_surfaces; i++) { |
| 208 | + surfaces[i].Info = q->req.Info; |
| 209 | + q->opaque_surfaces[i] = surfaces + i; |
| 210 | + } |
| 211 | + |
| 212 | + q->opaque_alloc.Header.BufferId = MFX_EXTBUFF_OPAQUE_SURFACE_ALLOCATION; |
| 213 | + q->opaque_alloc.Header.BufferSz = sizeof(q->opaque_alloc); |
| 214 | + q->opaque_alloc.In.Surfaces = q->opaque_surfaces; |
| 215 | + q->opaque_alloc.In.NumSurface = nb_surfaces; |
| 216 | + q->opaque_alloc.In.Type = q->req.Type; |
| 217 | + |
| 218 | + q->extparam_internal[q->nb_extparam_internal++] = (mfxExtBuffer *)&q->opaque_alloc; |
| 219 | + |
| 220 | + qsv->nb_opaque_surfaces = nb_surfaces; |
| 221 | + qsv->opaque_surfaces = q->opaque_alloc_buf; |
| 222 | + qsv->opaque_alloc_type = q->req.Type; |
| 223 | + |
| 224 | + return 0; |
| 225 | +} |
| 226 | + |
| 190 | 227 | int ff_qsv_enc_init(AVCodecContext *avctx, QSVEncContext *q) |
| 191 | 228 | { |
| 229 | + int opaque_alloc = 0; |
| 192 | 230 | int ret; |
| 193 | 231 | |
| 194 | 232 | q->param.IOPattern = MFX_IOPATTERN_IN_SYSTEM_MEMORY; |
| @@ -204,6 +242,8 @@ int ff_qsv_enc_init(AVCodecContext *avctx, QSVEncContext *q) · 9 unmodified lines |
| 204 | 242 | |
| 205 | 243 | q->session = qsv->session; |
| 206 | 244 | q->param.IOPattern = qsv->iopattern; |
| 245 | + |
| 246 | + opaque_alloc = qsv->opaque_alloc; |
| 207 | 247 | } |
| 208 | 248 | |
| 209 | 249 | if (!q->session) { |
| @@ -225,11 +265,17 @@ int ff_qsv_enc_init(AVCodecContext *avctx, QSVEncContext *q) · 15 unmodified lines |
| 225 | 265 | return ff_qsv_error(ret); |
| 226 | 266 | } |
| 227 | 267 | |
| 268 | + if (opaque_alloc) { |
| 269 | + ret = qsv_init_opaque_alloc(avctx, q); |
| 270 | + if (ret < 0) |
| 271 | + return ret; |
| 272 | + } |
| 273 | + |
| 228 | 274 | if (avctx->hwaccel_context) { |
| 229 | 275 | AVQSVContext *qsv = avctx->hwaccel_context; |
| 230 | 276 | int i, j; |
| 231 | 277 | |
| 232 | | − q->extparam = av_mallocz_array(qsv->nb_ext_buffers + FF_ARRAY_ELEMS(q->extparam_internal), |
| 278 | + q->extparam = av_mallocz_array(qsv->nb_ext_buffers + q->nb_extparam_internal, |
| 233 | 279 | sizeof(*q->extparam)); |
| 234 | 280 | if (!q->extparam) |
| 235 | 281 | return AVERROR(ENOMEM); |
| @@ -239,7 +285,7 @@ int ff_qsv_enc_init(AVCodecContext *avctx, QSVEncContext *q) · 3 unmodified lines |
| 239 | 285 | q->param.ExtParam[i] = qsv->ext_buffers[i]; |
| 240 | 286 | q->param.NumExtParam = qsv->nb_ext_buffers; |
| 241 | 287 | |
| 242 | | − for (i = 0; i < FF_ARRAY_ELEMS(q->extparam_internal); i++) { |
| 288 | + for (i = 0; i < q->nb_extparam_internal; i++) { |
| 243 | 289 | for (j = 0; j < qsv->nb_ext_buffers; j++) { |
| 244 | 290 | if (qsv->ext_buffers[j]->BufferId == q->extparam_internal[i]->BufferId) |
| 245 | 291 | break; |
| @@ -251,7 +297,7 @@ int ff_qsv_enc_init(AVCodecContext *avctx, QSVEncContext *q) · 5 unmodified lines |
| 251 | 297 | } |
| 252 | 298 | } else { |
| 253 | 299 | q->param.ExtParam = q->extparam_internal; |
| 254 | | − q->param.NumExtParam = FF_ARRAY_ELEMS(q->extparam_internal); |
| 300 | + q->param.NumExtParam = q->nb_extparam_internal; |
| 255 | 301 | } |
| 256 | 302 | |
| 257 | 303 | ret = MFXVideoENCODE_Init(q->session, &q->param); |
| @@ -537,6 +583,9 @@ int ff_qsv_enc_close(AVCodecContext *avctx, QSVEncContext *q) · 279 unmodified lines |
| 537 | 583 | av_fifo_free(q->async_fifo); |
| 538 | 584 | q->async_fifo = NULL; |
| 539 | 585 | |
| 586 | + av_freep(&q->opaque_surfaces); |
| 587 | + av_buffer_unref(&q->opaque_alloc_buf); |
| 588 | + |
| 540 | 589 | av_freep(&q->extparam); |
| 541 | 590 | |
| 542 | 591 | return 0; |