Factorises out existing surface initialisation code to reuse. (cherry picked from commit eaa5e0710496db50fc164806e5f49eaaccc83bb5)
Unified · Split
| @@ -94,6 +94,16 @@ static const struct { · 93 unmodified lines | |||
| 94 | { AV_PIX_FMT_PAL8, MFX_FOURCC_P8 }, | 94 | { AV_PIX_FMT_PAL8, MFX_FOURCC_P8 }, |
| 95 | }; | 95 | }; |
| 96 | 96 | ||
| 97 | static uint32_t qsv_fourcc_from_pix_fmt(enum AVPixelFormat pix_fmt) | ||
| 98 | { | ||
| 99 | int i; | ||
| 100 | for (i = 0; i < FF_ARRAY_ELEMS(supported_pixel_formats); i++) { | ||
| 101 | if (supported_pixel_formats[i].pix_fmt == pix_fmt) | ||
| 102 | return supported_pixel_formats[i].fourcc; | ||
| 103 | } | ||
| 104 | return 0; | ||
| 105 | } | ||
| 106 | |||
| 97 | static int qsv_device_init(AVHWDeviceContext *ctx) | 107 | static int qsv_device_init(AVHWDeviceContext *ctx) |
| 98 | { | 108 | { |
| 99 | AVQSVDeviceContext *hwctx = ctx->hwctx; | 109 | AVQSVDeviceContext *hwctx = ctx->hwctx; |
| @@ -272,18 +282,48 @@ fail: · 172 unmodified lines | |||
| 272 | return ret; | 282 | return ret; |
| 273 | } | 283 | } |
| 274 | 284 | ||
| 285 | static int qsv_init_surface(AVHWFramesContext *ctx, mfxFrameSurface1 *surf) | ||
| 286 | { | ||
| 287 | const AVPixFmtDescriptor *desc; | ||
| 288 | uint32_t fourcc; | ||
| 289 | |||
| 290 | desc = av_pix_fmt_desc_get(ctx->sw_format); | ||
| 291 | if (!desc) | ||
| 292 | return AVERROR(EINVAL); | ||
| 293 | |||
| 294 | fourcc = qsv_fourcc_from_pix_fmt(ctx->sw_format); | ||
| 295 | if (!fourcc) | ||
| 296 | return AVERROR(EINVAL); | ||
| 297 | |||
| 298 | surf->Info.BitDepthLuma = desc->comp[0].depth; | ||
| 299 | surf->Info.BitDepthChroma = desc->comp[0].depth; | ||
| 300 | surf->Info.Shift = desc->comp[0].depth > 8; | ||
| 301 | |||
| 302 | if (desc->log2_chroma_w && desc->log2_chroma_h) | ||
| 303 | surf->Info.ChromaFormat = MFX_CHROMAFORMAT_YUV420; | ||
| 304 | else if (desc->log2_chroma_w) | ||
| 305 | surf->Info.ChromaFormat = MFX_CHROMAFORMAT_YUV422; | ||
| 306 | else | ||
| 307 | surf->Info.ChromaFormat = MFX_CHROMAFORMAT_YUV444; | ||
| 308 | |||
| 309 | surf->Info.FourCC = fourcc; | ||
| 310 | surf->Info.Width = ctx->width; | ||
| 311 | surf->Info.CropW = ctx->width; | ||
| 312 | surf->Info.Height = ctx->height; | ||
| 313 | surf->Info.CropH = ctx->height; | ||
| 314 | surf->Info.FrameRateExtN = 25; | ||
| 315 | surf->Info.FrameRateExtD = 1; | ||
| 316 | |||
| 317 | return 0; | ||
| 318 | } | ||
| 319 | |||
| 275 | static int qsv_init_pool(AVHWFramesContext *ctx, uint32_t fourcc) | 320 | static int qsv_init_pool(AVHWFramesContext *ctx, uint32_t fourcc) |
| 276 | { | 321 | { |
| 277 | QSVFramesContext *s = ctx->internal->priv; | 322 | QSVFramesContext *s = ctx->internal->priv; |
| 278 | AVQSVFramesContext *frames_hwctx = ctx->hwctx; | 323 | AVQSVFramesContext *frames_hwctx = ctx->hwctx; |
| 279 | const AVPixFmtDescriptor *desc; | ||
| 280 | 324 | ||
| 281 | int i, ret = 0; | 325 | int i, ret = 0; |
| 282 | 326 | ||
| 283 | desc = av_pix_fmt_desc_get(ctx->sw_format); | ||
| 284 | if (!desc) | ||
| 285 | return AVERROR_BUG; | ||
| 286 | |||
| 287 | if (ctx->initial_pool_size <= 0) { | 327 | if (ctx->initial_pool_size <= 0) { |
| 288 | av_log(ctx, AV_LOG_ERROR, "QSV requires a fixed frame pool size\n"); | 328 | av_log(ctx, AV_LOG_ERROR, "QSV requires a fixed frame pool size\n"); |
| 289 | return AVERROR(EINVAL); | 329 | return AVERROR(EINVAL); |
| @@ -295,26 +335,9 @@ static int qsv_init_pool(AVHWFramesContext *ctx, uint32_t fourcc) · 5 unmodified lines | |||
| 295 | return AVERROR(ENOMEM); | 335 | return AVERROR(ENOMEM); |
| 296 | 336 | ||
| 297 | for (i = 0; i < ctx->initial_pool_size; i++) { | 337 | for (i = 0; i < ctx->initial_pool_size; i++) { |
| 298 | mfxFrameSurface1 *surf = &s->surfaces_internal[i]; | 338 | ret = qsv_init_surface(ctx, &s->surfaces_internal[i]); |
| 299 | 339 | if (ret < 0) | |
| 300 | surf->Info.BitDepthLuma = desc->comp[0].depth; | 340 | return ret; |
| 301 | surf->Info.BitDepthChroma = desc->comp[0].depth; | ||
| 302 | surf->Info.Shift = desc->comp[0].depth > 8; | ||
| 303 | |||
| 304 | if (desc->log2_chroma_w && desc->log2_chroma_h) | ||
| 305 | surf->Info.ChromaFormat = MFX_CHROMAFORMAT_YUV420; | ||
| 306 | else if (desc->log2_chroma_w) | ||
| 307 | surf->Info.ChromaFormat = MFX_CHROMAFORMAT_YUV422; | ||
| 308 | else | ||
| 309 | surf->Info.ChromaFormat = MFX_CHROMAFORMAT_YUV444; | ||
| 310 | |||
| 311 | surf->Info.FourCC = fourcc; | ||
| 312 | surf->Info.Width = ctx->width; | ||
| 313 | surf->Info.CropW = ctx->width; | ||
| 314 | surf->Info.Height = ctx->height; | ||
| 315 | surf->Info.CropH = ctx->height; | ||
| 316 | surf->Info.FrameRateExtN = 25; | ||
| 317 | surf->Info.FrameRateExtD = 1; | ||
| 318 | } | 341 | } |
| 319 | 342 | ||
| 320 | if (!(frames_hwctx->frame_type & MFX_MEMTYPE_OPAQUE_FRAME)) { | 343 | if (!(frames_hwctx->frame_type & MFX_MEMTYPE_OPAQUE_FRAME)) { |
| @@ -466,15 +489,10 @@ static int qsv_frames_init(AVHWFramesContext *ctx) · 145 unmodified lines | |||
| 466 | 489 | ||
| 467 | int opaque = !!(frames_hwctx->frame_type & MFX_MEMTYPE_OPAQUE_FRAME); | 490 | int opaque = !!(frames_hwctx->frame_type & MFX_MEMTYPE_OPAQUE_FRAME); |
| 468 | 491 | ||
| 469 | uint32_t fourcc = 0; | 492 | uint32_t fourcc; |
| 470 | int i, ret; | 493 | int i, ret; |
| 471 | 494 | ||
| 472 | for (i = 0; i < FF_ARRAY_ELEMS(supported_pixel_formats); i++) { | 495 | fourcc = qsv_fourcc_from_pix_fmt(ctx->sw_format); |
| 473 | if (supported_pixel_formats[i].pix_fmt == ctx->sw_format) { | ||
| 474 | fourcc = supported_pixel_formats[i].fourcc; | ||
| 475 | break; | ||
| 476 | } | ||
| 477 | } | ||
| 478 | if (!fourcc) { | 496 | if (!fourcc) { |
| 479 | av_log(ctx, AV_LOG_ERROR, "Unsupported pixel format\n"); | 497 | av_log(ctx, AV_LOG_ERROR, "Unsupported pixel format\n"); |
| 480 | return AVERROR(ENOSYS); | 498 | return AVERROR(ENOSYS); |
| @@ -723,6 +741,96 @@ static int qsv_transfer_data_to(AVHWFramesContext *ctx, AVFrame *dst, · 242 unmodified lines | |||
| 723 | return 0; | 741 | return 0; |
| 724 | } | 742 | } |
| 725 | 743 | ||
| 744 | static int qsv_frames_derive_to(AVHWFramesContext *dst_ctx, | ||
| 745 | AVHWFramesContext *src_ctx, int flags) | ||
| 746 | { | ||
| 747 | QSVFramesContext *s = dst_ctx->internal->priv; | ||
| 748 | AVQSVFramesContext *dst_hwctx = dst_ctx->hwctx; | ||
| 749 | int i; | ||
| 750 | |||
| 751 | switch (src_ctx->device_ctx->type) { | ||
| 752 | #if CONFIG_VAAPI | ||
| 753 | case AV_HWDEVICE_TYPE_VAAPI: | ||
| 754 | { | ||
| 755 | AVVAAPIFramesContext *src_hwctx = src_ctx->hwctx; | ||
| 756 | s->surfaces_internal = av_mallocz_array(src_hwctx->nb_surfaces, | ||
| 757 | sizeof(*s->surfaces_internal)); | ||
| 758 | if (!s->surfaces_internal) | ||
| 759 | return AVERROR(ENOMEM); | ||
| 760 | for (i = 0; i < src_hwctx->nb_surfaces; i++) { | ||
| 761 | qsv_init_surface(dst_ctx, &s->surfaces_internal[i]); | ||
| 762 | s->surfaces_internal[i].Data.MemId = src_hwctx->surface_ids + i; | ||
| 763 | } | ||
| 764 | dst_hwctx->nb_surfaces = src_hwctx->nb_surfaces; | ||
| 765 | dst_hwctx->frame_type = MFX_MEMTYPE_VIDEO_MEMORY_DECODER_TARGET; | ||
| 766 | } | ||
| 767 | break; | ||
| 768 | #endif | ||
| 769 | #if CONFIG_DXVA2 | ||
| 770 | case AV_HWDEVICE_TYPE_DXVA2: | ||
| 771 | { | ||
| 772 | AVDXVA2FramesContext *src_hwctx = src_ctx->hwctx; | ||
| 773 | s->surfaces_internal = av_mallocz_array(src_hwctx->nb_surfaces, | ||
| 774 | sizeof(*s->surfaces_internal)); | ||
| 775 | if (!s->surfaces_internal) | ||
| 776 | return AVERROR(ENOMEM); | ||
| 777 | for (i = 0; i < src_hwctx->nb_surfaces; i++) { | ||
| 778 | qsv_init_surface(dst_ctx, &s->surfaces_internal[i]); | ||
| 779 | s->surfaces_internal[i].Data.MemId = (mfxMemId)src_hwctx->surfaces[i]; | ||
| 780 | } | ||
| 781 | dst_hwctx->nb_surfaces = src_hwctx->nb_surfaces; | ||
| 782 | if (src_hwctx->surface_type == DXVA2_VideoProcessorRenderTarget) | ||
| 783 | dst_hwctx->frame_type = MFX_MEMTYPE_VIDEO_MEMORY_PROCESSOR_TARGET; | ||
| 784 | else | ||
| 785 | dst_hwctx->frame_type = MFX_MEMTYPE_VIDEO_MEMORY_DECODER_TARGET; | ||
| 786 | } | ||
| 787 | break; | ||
| 788 | #endif | ||
| 789 | default: | ||
| 790 | return AVERROR(ENOSYS); | ||
| 791 | } | ||
| 792 | |||
| 793 | dst_hwctx->surfaces = s->surfaces_internal; | ||
| 794 | |||
| 795 | return 0; | ||
| 796 | } | ||
| 797 | |||
| 798 | static int qsv_map_to(AVHWFramesContext *dst_ctx, | ||
| 799 | AVFrame *dst, const AVFrame *src, int flags) | ||
| 800 | { | ||
| 801 | AVQSVFramesContext *hwctx = dst_ctx->hwctx; | ||
| 802 | int i, err; | ||
| 803 | |||
| 804 | for (i = 0; i < hwctx->nb_surfaces; i++) { | ||
| 805 | #if CONFIG_VAAPI | ||
| 806 | if (*(VASurfaceID*)hwctx->surfaces[i].Data.MemId == | ||
| 807 | (VASurfaceID)(uintptr_t)src->data[3]) | ||
| 808 | break; | ||
| 809 | #endif | ||
| 810 | #if CONFIG_DXVA2 | ||
| 811 | if ((IDirect3DSurface9*)hwctx->surfaces[i].Data.MemId == | ||
| 812 | (IDirect3DSurface9*)(uintptr_t)src->data[3]) | ||
| 813 | break; | ||
| 814 | #endif | ||
| 815 | } | ||
| 816 | if (i >= hwctx->nb_surfaces) { | ||
| 817 | av_log(dst_ctx, AV_LOG_ERROR, "Trying to map from a surface which " | ||
| 818 | "is not in the mapped frames context.\n"); | ||
| 819 | return AVERROR(EINVAL); | ||
| 820 | } | ||
| 821 | |||
| 822 | err = ff_hwframe_map_create(dst->hw_frames_ctx, | ||
| 823 | dst, src, NULL, NULL); | ||
| 824 | if (err) | ||
| 825 | return err; | ||
| 826 | |||
| 827 | dst->width = src->width; | ||
| 828 | dst->height = src->height; | ||
| 829 | dst->data[3] = (uint8_t*)&hwctx->surfaces[i]; | ||
| 830 | |||
| 831 | return 0; | ||
| 832 | } | ||
| 833 | |||
| 726 | static int qsv_frames_get_constraints(AVHWDeviceContext *ctx, | 834 | static int qsv_frames_get_constraints(AVHWDeviceContext *ctx, |
| 727 | const void *hwconfig, | 835 | const void *hwconfig, |
| 728 | AVHWFramesConstraints *constraints) | 836 | AVHWFramesConstraints *constraints) |
| @@ -931,7 +1039,9 @@ const HWContextType ff_hwcontext_type_qsv = { · 202 unmodified lines | |||
| 931 | .transfer_get_formats = qsv_transfer_get_formats, | 1039 | .transfer_get_formats = qsv_transfer_get_formats, |
| 932 | .transfer_data_to = qsv_transfer_data_to, | 1040 | .transfer_data_to = qsv_transfer_data_to, |
| 933 | .transfer_data_from = qsv_transfer_data_from, | 1041 | .transfer_data_from = qsv_transfer_data_from, |
| 1042 | .map_to = qsv_map_to, | ||
| 934 | .map_from = qsv_map_from, | 1043 | .map_from = qsv_map_from, |
| 1044 | .frames_derive_to = qsv_frames_derive_to, | ||
| 935 | 1045 | ||
| 936 | .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_QSV, AV_PIX_FMT_NONE }, | 1046 | .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_QSV, AV_PIX_FMT_NONE }, |
| 937 | }; | 1047 | }; |