History

hwcontext_qsv: Implement mapping frames from the child device type

Factorises out existing surface initialisation code to reuse. (cherry picked from commit eaa5e0710496db50fc164806e5f49eaaccc83bb5)

Mark Thompson committed 9 years ago

Commit f82ace71 parent ec3dbea1 file · +142 −32Browse files

Unified · Split

libavutil/hwcontext_qsv.c+142−32
@@ -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
97static 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
97static int qsv_device_init(AVHWDeviceContext *ctx)107static 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
285static 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
275static int qsv_init_pool(AVHWFramesContext *ctx, uint32_t fourcc)320static 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
744static 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
798static 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
726static int qsv_frames_get_constraints(AVHWDeviceContext *ctx,834static 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};

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t