obs-studio/plugins/obs-qsv11/common_utils.cpp
Aidan Delaney 134ffe924f obs-qsv11: Remove Intel NDA from qsv11 plugin
Intel committed an NDA disclaimer on each source file.  The stated
intention was that the NDA "added to OBS doesn't apply to open source
code once it's been accepted by the community. You can remove it for
your modifications".  This quote is from an email chain involving
Intel's legal team and developers.  The NDA in the source files
mistakenly triggers source code scanners that look for license
violations.  I have removed the comments that contain the NDA.
2021-10-24 00:39:09 -07:00

300 lines
7.2 KiB
C++

#include "common_utils.h"
// =================================================================
// Utility functions, not directly tied to Intel Media SDK functionality
//
void PrintErrString(int err, const char *filestr, int line)
{
switch (err) {
case 0:
printf("\n No error.\n");
break;
case -1:
printf("\n Unknown error: %s %d\n", filestr, line);
break;
case -2:
printf("\n Null pointer. Check filename/path + permissions? %s %d\n",
filestr, line);
break;
case -3:
printf("\n Unsupported feature/library load error. %s %d\n",
filestr, line);
break;
case -4:
printf("\n Could not allocate memory. %s %d\n", filestr, line);
break;
case -5:
printf("\n Insufficient IO buffers. %s %d\n", filestr, line);
break;
case -6:
printf("\n Invalid handle. %s %d\n", filestr, line);
break;
case -7:
printf("\n Memory lock failure. %s %d\n", filestr, line);
break;
case -8:
printf("\n Function called before initialization. %s %d\n",
filestr, line);
break;
case -9:
printf("\n Specified object not found. %s %d\n", filestr, line);
break;
case -10:
printf("\n More input data expected. %s %d\n", filestr, line);
break;
case -11:
printf("\n More output surfaces expected. %s %d\n", filestr,
line);
break;
case -12:
printf("\n Operation aborted. %s %d\n", filestr, line);
break;
case -13:
printf("\n HW device lost. %s %d\n", filestr, line);
break;
case -14:
printf("\n Incompatible video parameters. %s %d\n", filestr,
line);
break;
case -15:
printf("\n Invalid video parameters. %s %d\n", filestr, line);
break;
case -16:
printf("\n Undefined behavior. %s %d\n", filestr, line);
break;
case -17:
printf("\n Device operation failure. %s %d\n", filestr, line);
break;
case -18:
printf("\n More bitstream data expected. %s %d\n", filestr,
line);
break;
case -19:
printf("\n Incompatible audio parameters. %s %d\n", filestr,
line);
break;
case -20:
printf("\n Invalid audio parameters. %s %d\n", filestr, line);
break;
default:
printf("\nError code %d,\t%s\t%d\n\n", err, filestr, line);
}
}
mfxStatus ReadPlaneData(mfxU16 w, mfxU16 h, mfxU8 *buf, mfxU8 *ptr,
mfxU16 pitch, mfxU16 offset, FILE *fSource)
{
mfxU32 nBytesRead;
for (mfxU16 i = 0; i < h; i++) {
nBytesRead = (mfxU32)fread(buf, 1, w, fSource);
if (w != nBytesRead)
return MFX_ERR_MORE_DATA;
for (mfxU16 j = 0; j < w; j++)
ptr[i * pitch + j * 2 + offset] = buf[j];
}
return MFX_ERR_NONE;
}
mfxStatus LoadRawFrame(mfxFrameSurface1 *pSurface, FILE *fSource)
{
if (!fSource) {
// Simulate instantaneous access to 1000 "empty" frames.
static int frameCount = 0;
if (1000 == frameCount++)
return MFX_ERR_MORE_DATA;
else
return MFX_ERR_NONE;
}
mfxStatus sts = MFX_ERR_NONE;
mfxU32 nBytesRead;
mfxU16 w, h, i, pitch;
mfxU8 *ptr;
mfxFrameInfo *pInfo = &pSurface->Info;
mfxFrameData *pData = &pSurface->Data;
if (pInfo->CropH > 0 && pInfo->CropW > 0) {
w = pInfo->CropW;
h = pInfo->CropH;
} else {
w = pInfo->Width;
h = pInfo->Height;
}
pitch = pData->Pitch;
ptr = pData->Y + pInfo->CropX + pInfo->CropY * pData->Pitch;
// read luminance plane
for (i = 0; i < h; i++) {
nBytesRead = (mfxU32)fread(ptr + i * pitch, 1, w, fSource);
if (w != nBytesRead)
return MFX_ERR_MORE_DATA;
}
mfxU8 buf[2048]; // maximum supported chroma width for nv12
w /= 2;
h /= 2;
ptr = pData->UV + pInfo->CropX + (pInfo->CropY / 2) * pitch;
if (w > 2048)
return MFX_ERR_UNSUPPORTED;
// load U
sts = ReadPlaneData(w, h, buf, ptr, pitch, 0, fSource);
if (MFX_ERR_NONE != sts)
return sts;
// load V
sts = ReadPlaneData(w, h, buf, ptr, pitch, 1, fSource);
if (MFX_ERR_NONE != sts)
return sts;
return MFX_ERR_NONE;
}
mfxStatus LoadRawRGBFrame(mfxFrameSurface1 *pSurface, FILE *fSource)
{
if (!fSource) {
// Simulate instantaneous access to 1000 "empty" frames.
static int frameCount = 0;
if (1000 == frameCount++)
return MFX_ERR_MORE_DATA;
else
return MFX_ERR_NONE;
}
size_t nBytesRead;
mfxU16 w, h;
mfxFrameInfo *pInfo = &pSurface->Info;
if (pInfo->CropH > 0 && pInfo->CropW > 0) {
w = pInfo->CropW;
h = pInfo->CropH;
} else {
w = pInfo->Width;
h = pInfo->Height;
}
for (mfxU16 i = 0; i < h; i++) {
nBytesRead = fread(pSurface->Data.B + i * pSurface->Data.Pitch,
1, w * 4, fSource);
if ((size_t)(w * 4) != nBytesRead)
return MFX_ERR_MORE_DATA;
}
return MFX_ERR_NONE;
}
mfxStatus WriteBitStreamFrame(mfxBitstream *pMfxBitstream, FILE *fSink)
{
mfxU32 nBytesWritten =
(mfxU32)fwrite(pMfxBitstream->Data + pMfxBitstream->DataOffset,
1, pMfxBitstream->DataLength, fSink);
if (nBytesWritten != pMfxBitstream->DataLength)
return MFX_ERR_UNDEFINED_BEHAVIOR;
pMfxBitstream->DataLength = 0;
return MFX_ERR_NONE;
}
mfxStatus ReadBitStreamData(mfxBitstream *pBS, FILE *fSource)
{
memmove(pBS->Data, pBS->Data + pBS->DataOffset, pBS->DataLength);
pBS->DataOffset = 0;
mfxU32 nBytesRead = (mfxU32)fread(pBS->Data + pBS->DataLength, 1,
pBS->MaxLength - pBS->DataLength,
fSource);
if (0 == nBytesRead)
return MFX_ERR_MORE_DATA;
pBS->DataLength += nBytesRead;
return MFX_ERR_NONE;
}
mfxStatus WriteSection(mfxU8 *plane, mfxU16 factor, mfxU16 chunksize,
mfxFrameInfo *pInfo, mfxFrameData *pData, mfxU32 i,
mfxU32 j, FILE *fSink)
{
if (chunksize != fwrite(plane +
(pInfo->CropY * pData->Pitch / factor +
pInfo->CropX) +
i * pData->Pitch + j,
1, chunksize, fSink))
return MFX_ERR_UNDEFINED_BEHAVIOR;
return MFX_ERR_NONE;
}
mfxStatus WriteRawFrame(mfxFrameSurface1 *pSurface, FILE *fSink)
{
mfxFrameInfo *pInfo = &pSurface->Info;
mfxFrameData *pData = &pSurface->Data;
mfxU32 i, j, h, w;
mfxStatus sts = MFX_ERR_NONE;
for (i = 0; i < pInfo->CropH; i++)
sts = WriteSection(pData->Y, 1, pInfo->CropW, pInfo, pData, i,
0, fSink);
h = pInfo->CropH / 2;
w = pInfo->CropW;
for (i = 0; i < h; i++)
for (j = 0; j < w; j += 2)
sts = WriteSection(pData->UV, 2, 1, pInfo, pData, i, j,
fSink);
for (i = 0; i < h; i++)
for (j = 1; j < w; j += 2)
sts = WriteSection(pData->UV, 2, 1, pInfo, pData, i, j,
fSink);
return sts;
}
int GetFreeTaskIndex(Task *pTaskPool, mfxU16 nPoolSize)
{
if (pTaskPool)
for (int i = 0; i < nPoolSize; i++)
if (!pTaskPool[i].syncp)
return i;
return MFX_ERR_NOT_FOUND;
}
void ClearYUVSurfaceSysMem(mfxFrameSurface1 *pSfc, mfxU16 width, mfxU16 height)
{
// In case simulating direct access to frames we initialize the allocated surfaces with default pattern
memset(pSfc->Data.Y, 100, width * height); // Y plane
memset(pSfc->Data.U, 50, (width * height) / 2); // UV plane
}
// Get free raw frame surface
int GetFreeSurfaceIndex(mfxFrameSurface1 **pSurfacesPool, mfxU16 nPoolSize)
{
if (pSurfacesPool)
for (mfxU16 i = 0; i < nPoolSize; i++)
if (0 == pSurfacesPool[i]->Data.Locked)
return i;
return MFX_ERR_NOT_FOUND;
}
char mfxFrameTypeString(mfxU16 FrameType)
{
mfxU8 FrameTmp = FrameType & 0xF;
char FrameTypeOut;
switch (FrameTmp) {
case MFX_FRAMETYPE_I:
FrameTypeOut = 'I';
break;
case MFX_FRAMETYPE_P:
FrameTypeOut = 'P';
break;
case MFX_FRAMETYPE_B:
FrameTypeOut = 'B';
break;
default:
FrameTypeOut = '*';
}
return FrameTypeOut;
}