| @@ -134,7 +134,7 @@ static int init_video_param(AVCodecContext *avctx, QSVEncContext *q) · 133 unmodified lines |
| 134 | q->extco.CAVLC = avctx->coder_type == FF_CODER_TYPE_VLC ? | 134 | q->extco.CAVLC = avctx->coder_type == FF_CODER_TYPE_VLC ? |
| 135 | MFX_CODINGOPTION_ON : MFX_CODINGOPTION_UNKNOWN; | 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 | return 0; | 140 | return 0; |
| @@ -187,8 +187,46 @@ static int qsv_retrieve_enc_params(AVCodecContext *avctx, QSVEncContext *q) · 46 unmodified lines |
| 187 | return 0; | 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 | int ff_qsv_enc_init(AVCodecContext *avctx, QSVEncContext *q) | 227 | int ff_qsv_enc_init(AVCodecContext *avctx, QSVEncContext *q) |
| 191 | { | 228 | { |
| | 229 | int opaque_alloc = 0; |
| 192 | int ret; | 230 | int ret; |
| 193 | | 231 | |
| 194 | q->param.IOPattern = MFX_IOPATTERN_IN_SYSTEM_MEMORY; | 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 | q->session = qsv->session; | 243 | q->session = qsv->session; |
| 206 | q->param.IOPattern = qsv->iopattern; | 244 | q->param.IOPattern = qsv->iopattern; |
| | 245 | |
| | 246 | opaque_alloc = qsv->opaque_alloc; |
| 207 | } | 247 | } |
| 208 | | 248 | |
| 209 | if (!q->session) { | 249 | if (!q->session) { |
| @@ -225,11 +265,17 @@ int ff_qsv_enc_init(AVCodecContext *avctx, QSVEncContext *q) · 15 unmodified lines |
| 225 | return ff_qsv_error(ret); | 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 | if (avctx->hwaccel_context) { | 274 | if (avctx->hwaccel_context) { |
| 229 | AVQSVContext *qsv = avctx->hwaccel_context; | 275 | AVQSVContext *qsv = avctx->hwaccel_context; |
| 230 | int i, j; | 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 | sizeof(*q->extparam)); | 279 | sizeof(*q->extparam)); |
| 234 | if (!q->extparam) | 280 | if (!q->extparam) |
| 235 | return AVERROR(ENOMEM); | 281 | return AVERROR(ENOMEM); |
| @@ -239,7 +285,7 @@ int ff_qsv_enc_init(AVCodecContext *avctx, QSVEncContext *q) · 3 unmodified lines |
| 239 | q->param.ExtParam[i] = qsv->ext_buffers[i]; | 285 | q->param.ExtParam[i] = qsv->ext_buffers[i]; |
| 240 | q->param.NumExtParam = qsv->nb_ext_buffers; | 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 | for (j = 0; j < qsv->nb_ext_buffers; j++) { | 289 | for (j = 0; j < qsv->nb_ext_buffers; j++) { |
| 244 | if (qsv->ext_buffers[j]->BufferId == q->extparam_internal[i]->BufferId) | 290 | if (qsv->ext_buffers[j]->BufferId == q->extparam_internal[i]->BufferId) |
| 245 | break; | 291 | break; |
| @@ -251,7 +297,7 @@ int ff_qsv_enc_init(AVCodecContext *avctx, QSVEncContext *q) · 5 unmodified lines |
| 251 | } | 297 | } |
| 252 | } else { | 298 | } else { |
| 253 | q->param.ExtParam = q->extparam_internal; | 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 | ret = MFXVideoENCODE_Init(q->session, &q->param); | 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 | av_fifo_free(q->async_fifo); | 583 | av_fifo_free(q->async_fifo); |
| 538 | q->async_fifo = NULL; | 584 | q->async_fifo = NULL; |
| 539 | | 585 | |
| | 586 | av_freep(&q->opaque_surfaces); |
| | 587 | av_buffer_unref(&q->opaque_alloc_buf); |
| | 588 | |
| 540 | av_freep(&q->extparam); | 589 | av_freep(&q->extparam); |
| 541 | | 590 | |
| 542 | return 0; | 591 | return 0; |