Skip to content
This repository has been archived by the owner on May 20, 2024. It is now read-only.

Commit

Permalink
Release 2021.6.0
Browse files Browse the repository at this point in the history
New in This Release
===================

* Updated CPU runtime to API 2.5
* HEVC 4:2:2 planar decode support added to CPU runtime

For more information on the preview C++/Python APIs and Samples, see
https://software.intel.com/content/www/us/en/develop/articles/onevpl-preview-examples.html

oneVPL 2021.6.0 has been updated to include functional and security
updates. Users should update to the latest version.
  • Loading branch information
mav-intel committed Sep 13, 2021
1 parent a259736 commit d322e7e
Show file tree
Hide file tree
Showing 23 changed files with 1,703 additions and 214 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ install(
COMPONENT license)

include(cmake/PackageTarget.cmake)
include(InstallRequiredSystemLibraries)

if(BUILD_TESTS)
enable_testing()
Expand Down
18 changes: 9 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# oneAPI Video Processing Library CPU Implementation
# ![oneAPI](assets/oneapi-logo.png "oneAPI") Video Processing Library CPU Implementation

The oneAPI Video Processing Library (oneVPL) provides a single video processing
API for encode, decode, and video processing that works across a wide range of
Expand All @@ -12,9 +12,9 @@ This repository contains a CPU implementation of the specification.
as part of the [oneVPL base repository](https://github.com/oneapi-src/oneVPL).

---
This project is part of the larger [oneAPI](https://www.oneapi.com/) project.
See the [oneAPI Specification](https://spec.oneapi.com) and
[oneVPL Specification](https://spec.oneapi.com/versions/latest/elements/oneVPL/source/index.html)
This project is part of the larger [oneAPI](https://www.oneapi.io/) project.
See the [oneAPI Specification](https://spec.oneapi.io) and
[oneVPL Specification](https://spec.oneapi.io/versions/latest/elements/oneVPL/source/index.html)
for more information.


Expand Down Expand Up @@ -61,26 +61,26 @@ Video processing (+raw frame formats) supported by the CPU software implementati
|---------------|-------------|-------------|

Note: I420 = 8 bit/420. I010=10 bit/420.


## Installation
You can install oneVPL CPU implementation:

- from [oneVPL home page](https://software.intel.com/content/www/us/en/develop/tools/oneapi/components/onevpl.html) as a part of Intel® oneAPI Base Toolkit or standalone.

### Installation from Source
### Installation from Source
See [Installation from Sources](INSTALL.md) for details.

## Usage

### Configure the Environment

If you install to standard system locations, applications can find the dispatcher library and
If you install to standard system locations, applications can find the dispatcher library and
the dispatcher's default search rules will find your CPU implementation.

Otherwise you need to set up the environment search paths. This is easiest to manage when the
install location <vpl-install-location> for oneVPL base is the same directory as used for the
CPU implementation. In that case you can use the following steps:
install location <vpl-install-location> for oneVPL base is the same directory as used for the
CPU implementation. In that case you can use the following steps:

For Linux:
```
Expand Down
Binary file added assets/oneapi-logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 6 additions & 0 deletions cmake/oneAPIInstallDirs.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -72,3 +72,9 @@ foreach(
gnuinstalldirs_get_absolute_install_dir(ONEAPI_INSTALL_FULL_${dir}
ONEAPI_INSTALL_${dir} ${dir})
endforeach()

if(WIN32)
set(CMAKE_INSTALL_SYSTEM_RUNTIME_DESTINATION ${CMAKE_INSTALL_BINDIR})
else()
set(CMAKE_INSTALL_SYSTEM_RUNTIME_DESTINATION ${CMAKE_INSTALL_LIBDIR})
endif()
69 changes: 63 additions & 6 deletions cpu/src/cpu_common.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ AVPixelFormat MFXFourCC2AVPixelFormat(uint32_t fourcc) {
return AV_PIX_FMT_BGRA;
case MFX_FOURCC_I420:
return AV_PIX_FMT_YUV420P;
case MFX_FOURCC_I422:
return AV_PIX_FMT_YUV422P;
case MFX_FOURCC_I210:
return AV_PIX_FMT_YUV422P10LE;
}
return (AVPixelFormat)-1;
}
Expand All @@ -35,8 +39,10 @@ uint32_t AVPixelFormat2MFXFourCC(int format) {
return MFX_FOURCC_RGB4;
case AV_PIX_FMT_YUV420P:
return MFX_FOURCC_I420;
default:
return 0;
case AV_PIX_FMT_YUV422P:
return MFX_FOURCC_I422;
case AV_PIX_FMT_YUV422P10LE:
return MFX_FOURCC_I210;
}
return 0;
}
Expand Down Expand Up @@ -95,6 +101,18 @@ mfxStatus AVFrame2mfxFrameSurface(mfxFrameSurface1 *surface,
info->BitDepthChroma = 10;
info->ChromaFormat = MFX_CHROMAFORMAT_YUV420;
break;
case AV_PIX_FMT_YUV422P10LE:
info->FourCC = MFX_FOURCC_I210;
info->BitDepthLuma = 10;
info->BitDepthChroma = 10;
info->ChromaFormat = MFX_CHROMAFORMAT_YUV422;
break;
case AV_PIX_FMT_YUV422P:
info->FourCC = MFX_FOURCC_I422;
info->BitDepthLuma = 8;
info->BitDepthChroma = 8;
info->ChromaFormat = MFX_CHROMAFORMAT_YUV422;
break;
case AV_PIX_FMT_YUV420P:
case AV_PIX_FMT_YUVJ420P:
info->FourCC = MFX_FOURCC_IYUV;
Expand Down Expand Up @@ -135,6 +153,18 @@ mfxStatus AVFrame2mfxFrameSurface(mfxFrameSurface1 *surface,
w = info->Width;
h = info->Height;
}
else if (frame->format == AV_PIX_FMT_YUV422P10LE) {
RET_IF_FALSE(info->FourCC == MFX_FOURCC_I210, MFX_ERR_INCOMPATIBLE_VIDEO_PARAM);

w = info->Width * 2;
h = info->Height;
}
else if (frame->format == AV_PIX_FMT_YUV422P) {
RET_IF_FALSE(info->FourCC == MFX_FOURCC_I422, MFX_ERR_INCOMPATIBLE_VIDEO_PARAM);

w = info->Width;
h = info->Height;
}
else if (frame->format == AV_PIX_FMT_BGRA) {
RET_IF_FALSE(info->FourCC == MFX_FOURCC_RGB4, MFX_ERR_INCOMPATIBLE_VIDEO_PARAM);

Expand All @@ -153,6 +183,25 @@ mfxStatus AVFrame2mfxFrameSurface(mfxFrameSurface1 *surface,
memcpy_s(data->B + offset, w, frame->data[0] + y * frame->linesize[0], w);
}
}
else if ((frame->format == AV_PIX_FMT_YUV422P) || (frame->format == AV_PIX_FMT_YUV422P10LE)) {
// copy Y plane
for (y = 0; y < h; y++) {
offset = pitch * (y + info->CropY) + info->CropX;
memcpy_s(data->Y + offset, w, frame->data[0] + y * frame->linesize[0], w);
}

// copy U plane
for (y = 0; y < h; y++) {
offset = pitch / 2 * (y + info->CropY) + info->CropX;
memcpy_s(data->U + offset, w / 2, frame->data[1] + y * frame->linesize[1], w / 2);
}

// copy V plane
for (y = 0; y < h; y++) {
offset = pitch / 2 * (y + info->CropY) + info->CropX;
memcpy_s(data->V + offset, w / 2, frame->data[2] + y * frame->linesize[2], w / 2);
}
}
else {
// copy Y plane
for (y = 0; y < h; y++) {
Expand Down Expand Up @@ -187,6 +236,8 @@ mfxStatus CheckFrameInfoCommon(mfxFrameInfo *info, mfxU32 codecId) {
switch (info->FourCC) {
case MFX_FOURCC_I420:
case MFX_FOURCC_I010:
case MFX_FOURCC_I422:
case MFX_FOURCC_I210:
break;
default:
return MFX_ERR_INVALID_VIDEO_PARAM;
Expand All @@ -207,6 +258,7 @@ mfxStatus CheckFrameInfoCommon(mfxFrameInfo *info, mfxU32 codecId) {
if (info->BitDepthLuma > 8 || info->BitDepthChroma > 8) {
switch (info->FourCC) {
case MFX_FOURCC_I010:
case MFX_FOURCC_I210:
//case MFX_FOURCC_P010: // for later
break;
default:
Expand All @@ -219,7 +271,9 @@ mfxStatus CheckFrameInfoCommon(mfxFrameInfo *info, mfxU32 codecId) {
// RET_IF_FALSE(info->Shift, MFX_ERR_INVALID_VIDEO_PARAM);
//}

RET_IF_FALSE(info->ChromaFormat == MFX_CHROMAFORMAT_YUV420, MFX_ERR_INVALID_VIDEO_PARAM);
RET_IF_FALSE((info->ChromaFormat == MFX_CHROMAFORMAT_YUV420) ||
(info->ChromaFormat == MFX_CHROMAFORMAT_YUV422),
MFX_ERR_INVALID_VIDEO_PARAM);
RET_IF_FALSE((info->FrameRateExtN == 0 && info->FrameRateExtD == 0) ||
(info->FrameRateExtN != 0 && info->FrameRateExtD != 0),
MFX_ERR_INCOMPATIBLE_VIDEO_PARAM);
Expand All @@ -242,7 +296,8 @@ mfxStatus CheckFrameInfoCodecs(mfxFrameInfo *info, mfxU32 codecId) {
case MFX_CODEC_AVC:
case MFX_CODEC_HEVC:
case MFX_CODEC_AV1:
if (info->FourCC != MFX_FOURCC_I420 && info->FourCC != MFX_FOURCC_I010)
if (info->FourCC != MFX_FOURCC_I420 && info->FourCC != MFX_FOURCC_I010 &&
info->FourCC != MFX_FOURCC_I422 && info->FourCC != MFX_FOURCC_I210)
return MFX_ERR_INVALID_VIDEO_PARAM;
break;
default:
Expand All @@ -255,11 +310,13 @@ mfxStatus CheckFrameInfoCodecs(mfxFrameInfo *info, mfxU32 codecId) {
case MFX_CODEC_AVC:
case MFX_CODEC_HEVC:
case MFX_CODEC_AV1:
if (info->ChromaFormat != MFX_CHROMAFORMAT_YUV420)
if (info->ChromaFormat != MFX_CHROMAFORMAT_YUV420 &&
info->ChromaFormat != MFX_CHROMAFORMAT_YUV422)
return MFX_ERR_INVALID_VIDEO_PARAM;
break;
default:
RET_IF_FALSE(info->ChromaFormat == MFX_CHROMAFORMAT_YUV420,
RET_IF_FALSE(info->ChromaFormat == MFX_CHROMAFORMAT_YUV420 ||
info->ChromaFormat == MFX_CHROMAFORMAT_YUV422,
MFX_ERR_INVALID_VIDEO_PARAM);
break;
}
Expand Down
6 changes: 6 additions & 0 deletions cpu/src/cpu_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#ifndef CPU_SRC_CPU_COMMON_H_
#define CPU_SRC_CPU_COMMON_H_

#include <algorithm>
#include <chrono>
#include <future>
#include <map>
Expand All @@ -16,8 +17,13 @@

#include "vpl/mfxjpeg.h"
#include "vpl/mfxstructures.h"
#include "vpl/mfxsurfacepool.h"
#include "vpl/mfxvideo.h"

static inline bool operator==(mfxGUID const &l, mfxGUID const &r) {
return std::equal(l.Data, l.Data + 16, r.Data);
}

#define ENABLE_LIBAV_AUTO_THREADS

// TODO(m) do we need this?
Expand Down
68 changes: 64 additions & 4 deletions cpu/src/cpu_decode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,12 +74,14 @@ mfxStatus CpuDecode::ValidateDecodeParams(mfxVideoParam *par, bool canCorrect) {
if (par->mfx.NumThread)
return MFX_ERR_INVALID_VIDEO_PARAM;

//only YUV420 or YUV422 chromaformats accepted
if ((par->mfx.FrameInfo.ChromaFormat) &&
(par->mfx.FrameInfo.ChromaFormat != MFX_CHROMAFORMAT_YUV420))
!((par->mfx.FrameInfo.ChromaFormat == MFX_CHROMAFORMAT_YUV420) ||
(par->mfx.FrameInfo.ChromaFormat == MFX_CHROMAFORMAT_YUV422)))
return MFX_ERR_INVALID_VIDEO_PARAM;
}

//only I420 and I010 colorspaces allowed
//only I420, I422, I010, and and I210 colorspaces allowed
switch (par->mfx.FrameInfo.FourCC) {
case MFX_FOURCC_I420:
if (canCorrect) {
Expand All @@ -101,6 +103,26 @@ mfxStatus CpuDecode::ValidateDecodeParams(mfxVideoParam *par, bool canCorrect) {
return MFX_ERR_INVALID_VIDEO_PARAM;
}
break;
case MFX_FOURCC_I422:
if (canCorrect) {
if (par->mfx.FrameInfo.BitDepthLuma && par->mfx.FrameInfo.BitDepthLuma != 8)
fixedIncompatible = true;
if (par->mfx.FrameInfo.BitDepthChroma && par->mfx.FrameInfo.BitDepthChroma != 8)
fixedIncompatible = true;
par->mfx.FrameInfo.BitDepthLuma = 8;
par->mfx.FrameInfo.BitDepthChroma = 8;
par->mfx.FrameInfo.ChromaFormat = MFX_CHROMAFORMAT_YUV422;
}
else {
if (par->mfx.FrameInfo.BitDepthLuma && (par->mfx.FrameInfo.BitDepthLuma != 8))
return MFX_ERR_INVALID_VIDEO_PARAM;
if (par->mfx.FrameInfo.BitDepthChroma && (par->mfx.FrameInfo.BitDepthChroma != 8))
return MFX_ERR_INVALID_VIDEO_PARAM;
if (par->mfx.FrameInfo.ChromaFormat &&
(par->mfx.FrameInfo.ChromaFormat != MFX_CHROMAFORMAT_YUV422))
return MFX_ERR_INVALID_VIDEO_PARAM;
}
break;
case MFX_FOURCC_I010:
if (canCorrect) {
if (par->mfx.FrameInfo.BitDepthLuma && par->mfx.FrameInfo.BitDepthLuma != 10)
Expand All @@ -121,6 +143,26 @@ mfxStatus CpuDecode::ValidateDecodeParams(mfxVideoParam *par, bool canCorrect) {
return MFX_ERR_INVALID_VIDEO_PARAM;
}
break;
case MFX_FOURCC_I210:
if (canCorrect) {
if (par->mfx.FrameInfo.BitDepthLuma && par->mfx.FrameInfo.BitDepthLuma != 10)
fixedIncompatible = true;
if (par->mfx.FrameInfo.BitDepthChroma && par->mfx.FrameInfo.BitDepthChroma != 10)
fixedIncompatible = true;
par->mfx.FrameInfo.BitDepthLuma = 10;
par->mfx.FrameInfo.BitDepthChroma = 10;
par->mfx.FrameInfo.ChromaFormat = MFX_CHROMAFORMAT_YUV422;
}
else {
if (par->mfx.FrameInfo.BitDepthLuma && (par->mfx.FrameInfo.BitDepthLuma != 10))
return MFX_ERR_INVALID_VIDEO_PARAM;
if (par->mfx.FrameInfo.BitDepthChroma && (par->mfx.FrameInfo.BitDepthChroma != 10))
return MFX_ERR_INVALID_VIDEO_PARAM;
if (par->mfx.FrameInfo.ChromaFormat &&
(par->mfx.FrameInfo.ChromaFormat != MFX_CHROMAFORMAT_YUV422))
return MFX_ERR_INVALID_VIDEO_PARAM;
}
break;
default:
return MFX_ERR_INVALID_VIDEO_PARAM;
}
Expand Down Expand Up @@ -225,8 +267,8 @@ mfxStatus CpuDecode::InitDecode(mfxVideoParam *par, mfxBitstream *bs) {
// todo: this only works if input is large enough to
// decode a frame
mfxBitstream bs2 = *bs;
bs2.DataFlag = MFX_BITSTREAM_EOS;
m_bStreamInfo = true;
bs2.DataFlag |= MFX_BITSTREAM_EOS;
m_bStreamInfo = true;
DecodeFrame(&bs2, nullptr, nullptr);
GetVideoParam(par);
}
Expand Down Expand Up @@ -420,6 +462,12 @@ mfxStatus CpuDecode::DecodeFrame(mfxBitstream *bs,
case AV_PIX_FMT_YUV420P10LE:
m_param.mfx.FrameInfo.FourCC = MFX_FOURCC_I010;
break;
case AV_PIX_FMT_YUV422P10LE:
m_param.mfx.FrameInfo.FourCC = MFX_FOURCC_I210;
break;
case AV_PIX_FMT_YUV422P:
m_param.mfx.FrameInfo.FourCC = MFX_FOURCC_I422;
break;
case AV_PIX_FMT_YUV420P:
case AV_PIX_FMT_YUVJ420P:
default:
Expand Down Expand Up @@ -641,6 +689,18 @@ mfxStatus CpuDecode::GetVideoParam(mfxVideoParam *par) {
par->mfx.FrameInfo.BitDepthChroma = 8;
par->mfx.FrameInfo.ChromaFormat = MFX_CHROMAFORMAT_YUV420;
break;
case AV_PIX_FMT_YUV422P10LE:
par->mfx.FrameInfo.FourCC = MFX_FOURCC_I210;
par->mfx.FrameInfo.BitDepthLuma = 10;
par->mfx.FrameInfo.BitDepthChroma = 10;
par->mfx.FrameInfo.ChromaFormat = MFX_CHROMAFORMAT_YUV422;
break;
case AV_PIX_FMT_YUV422P:
par->mfx.FrameInfo.FourCC = MFX_FOURCC_I422;
par->mfx.FrameInfo.BitDepthLuma = 8;
par->mfx.FrameInfo.BitDepthChroma = 8;
par->mfx.FrameInfo.ChromaFormat = MFX_CHROMAFORMAT_YUV422;
break;
default:
//zero value after decodeheader indicates that
//a supported decode fourcc could not be found
Expand Down
4 changes: 3 additions & 1 deletion cpu/src/cpu_encode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -518,7 +518,9 @@ mfxStatus CpuEncode::InitEncode(mfxVideoParam *par) {
m_avEncContext->gop_size = par->mfx.GopPicSize;
// In case Jpeg, max_b_frames must be 0, otherwise avcodec_open2()'s crashed
m_avEncContext->max_b_frames =
(m_param.mfx.CodecId == MFX_CODEC_JPEG) ? 0 : par->mfx.GopRefDist;
(m_param.mfx.CodecId == MFX_CODEC_JPEG || par->mfx.GopRefDist == 0)
? 0
: (par->mfx.GopRefDist - 1);
m_avEncContext->bit_rate = par->mfx.TargetKbps * 1000; // prop is in kbps;

m_avEncContext->framerate.num = par->mfx.FrameInfo.FrameRateExtN;
Expand Down
20 changes: 20 additions & 0 deletions cpu/src/cpu_frame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -149,5 +149,25 @@ mfxStatus CpuFrame::QueryInterface(mfxFrameSurface1 *surface, mfxGUID guid, mfxH
RET_IF_FALSE(surface, MFX_ERR_NULL_PTR);
RET_IF_FALSE(interface, MFX_ERR_NULL_PTR);

CpuFrame *cpu_frame = TryCast(surface);
RET_IF_FALSE(cpu_frame, MFX_ERR_INVALID_HANDLE);

if (guid == (mfxGUID)MFX_GUID_SURFACE_POOL) {
CpuFramePoolInterface *parentPoolInterface = cpu_frame->m_parentPoolInterface;
RET_IF_FALSE(parentPoolInterface, MFX_ERR_NOT_INITIALIZED);

mfxSurfacePoolInterface *poolInterface = &(parentPoolInterface->m_surfacePoolInterface);
RET_IF_FALSE(poolInterface, MFX_ERR_NOT_INITIALIZED);

if (poolInterface->Context == nullptr)
return MFX_ERR_NOT_INITIALIZED;

// increase refcount every time interface is requested via QueryInterface
poolInterface->AddRef(poolInterface);

*interface = (mfxHDL)poolInterface;
return MFX_ERR_NONE;
}

return MFX_ERR_NOT_IMPLEMENTED;
}
Loading

0 comments on commit d322e7e

Please sign in to comment.