obs-studio/plugins/obs-qsv11/common_utils.cpp

304 lines
7.3 KiB
C++

#include "common_utils.h"
// =================================================================
// Utility functions, not directly tied to Intel Media SDK functionality
//
struct adapter_info adapters[MAX_ADAPTERS] = {0};
size_t adapter_count = 0;
size_t adapter_index = 0;
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;
}