diff --git a/libavcodec/qsv.c b/libavcodec/qsv.c index f38c617fc3..7af154202c 100644 --- a/libavcodec/qsv.c +++ b/libavcodec/qsv.c @@ -213,6 +213,11 @@ enum AVPixelFormat ff_qsv_map_fourcc(uint32_t fourcc) case MFX_FOURCC_Y210: return AV_PIX_FMT_Y210; case MFX_FOURCC_AYUV: return AV_PIX_FMT_VUYX; case MFX_FOURCC_Y410: return AV_PIX_FMT_XV30; +#if QSV_VERSION_ATLEAST(1, 31) + case MFX_FOURCC_P016: return AV_PIX_FMT_P012; + case MFX_FOURCC_Y216: return AV_PIX_FMT_Y212; + case MFX_FOURCC_Y416: return AV_PIX_FMT_XV36; +#endif #endif } return AV_PIX_FMT_NONE; @@ -259,6 +264,20 @@ int ff_qsv_map_pixfmt(enum AVPixelFormat format, uint32_t *fourcc, uint16_t *shi *fourcc = MFX_FOURCC_Y410; *shift = 0; return AV_PIX_FMT_XV30; +#if QSV_VERSION_ATLEAST(1, 31) + case AV_PIX_FMT_P012: + *fourcc = MFX_FOURCC_P016; + *shift = 1; + return AV_PIX_FMT_P012; + case AV_PIX_FMT_Y212: + *fourcc = MFX_FOURCC_Y216; + *shift = 1; + return AV_PIX_FMT_Y212; + case AV_PIX_FMT_XV36: + *fourcc = MFX_FOURCC_Y416; + *shift = 1; + return AV_PIX_FMT_XV36; +#endif #endif default: return AVERROR(ENOSYS); @@ -270,6 +289,7 @@ int ff_qsv_map_frame_to_surface(const AVFrame *frame, mfxFrameSurface1 *surface) switch (frame->format) { case AV_PIX_FMT_NV12: case AV_PIX_FMT_P010: + case AV_PIX_FMT_P012: surface->Data.Y = frame->data[0]; surface->Data.UV = frame->data[1]; /* The SDK checks Data.V when using system memory for VP9 encoding */ @@ -289,6 +309,7 @@ int ff_qsv_map_frame_to_surface(const AVFrame *frame, mfxFrameSurface1 *surface) break; case AV_PIX_FMT_Y210: + case AV_PIX_FMT_Y212: surface->Data.Y16 = (mfxU16 *)frame->data[0]; surface->Data.U16 = (mfxU16 *)frame->data[0] + 1; surface->Data.V16 = (mfxU16 *)frame->data[0] + 3; @@ -307,6 +328,15 @@ int ff_qsv_map_frame_to_surface(const AVFrame *frame, mfxFrameSurface1 *surface) surface->Data.U = frame->data[0]; break; + case AV_PIX_FMT_XV36: + surface->Data.U = frame->data[0]; + surface->Data.Y = frame->data[0] + 2; + surface->Data.V = frame->data[0] + 4; + // Only set Data.A to a valid address, the SDK doesn't + // use the value from the frame. + surface->Data.A = frame->data[0] + 6; + break; + default: return AVERROR(ENOSYS); } diff --git a/libavcodec/qsvdec.c b/libavcodec/qsvdec.c index 912d58965a..73405b5747 100644 --- a/libavcodec/qsvdec.c +++ b/libavcodec/qsvdec.c @@ -137,14 +137,19 @@ static int qsv_get_continuous_buffer(AVCodecContext *avctx, AVFrame *frame, frame->linesize[0] = FFALIGN(avctx->width, 128); break; case AV_PIX_FMT_P010: + case AV_PIX_FMT_P012: case AV_PIX_FMT_YUYV422: frame->linesize[0] = 2 * FFALIGN(avctx->width, 128); break; case AV_PIX_FMT_Y210: case AV_PIX_FMT_VUYX: case AV_PIX_FMT_XV30: + case AV_PIX_FMT_Y212: frame->linesize[0] = 4 * FFALIGN(avctx->width, 128); break; + case AV_PIX_FMT_XV36: + frame->linesize[0] = 8 * FFALIGN(avctx->width, 128); + break; default: av_log(avctx, AV_LOG_ERROR, "Unsupported pixel format.\n"); return AVERROR(EINVAL); @@ -156,7 +161,8 @@ static int qsv_get_continuous_buffer(AVCodecContext *avctx, AVFrame *frame, frame->data[0] = frame->buf[0]->data; if (avctx->pix_fmt == AV_PIX_FMT_NV12 || - avctx->pix_fmt == AV_PIX_FMT_P010) { + avctx->pix_fmt == AV_PIX_FMT_P010 || + avctx->pix_fmt == AV_PIX_FMT_P012) { frame->linesize[1] = frame->linesize[0]; frame->data[1] = frame->data[0] + frame->linesize[0] * FFALIGN(avctx->height, 64); @@ -1041,10 +1047,13 @@ const FFCodec ff_##x##_qsv_decoder = { \ .p.priv_class = &x##_qsv_class, \ .p.pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_NV12, \ AV_PIX_FMT_P010, \ + AV_PIX_FMT_P012, \ AV_PIX_FMT_YUYV422, \ AV_PIX_FMT_Y210, \ + AV_PIX_FMT_Y212, \ AV_PIX_FMT_VUYX, \ AV_PIX_FMT_XV30, \ + AV_PIX_FMT_XV36, \ AV_PIX_FMT_QSV, \ AV_PIX_FMT_NONE }, \ .hw_configs = qsv_hw_configs, \ diff --git a/libavcodec/qsvenc_hevc.c b/libavcodec/qsvenc_hevc.c index 1e1574a6f2..8127fcc6c3 100644 --- a/libavcodec/qsvenc_hevc.c +++ b/libavcodec/qsvenc_hevc.c @@ -310,6 +310,7 @@ const FFCodec ff_hevc_qsv_encoder = { .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HYBRID, .p.pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_NV12, AV_PIX_FMT_P010, + AV_PIX_FMT_P012, AV_PIX_FMT_YUYV422, AV_PIX_FMT_Y210, AV_PIX_FMT_QSV,