You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

337 lines
9.2 KiB

//-----------------------------------------------------------------------------
// COPYRIGHT (C) 2020 CHIPS&MEDIA INC. ALL RIGHTS RESERVED
//
// This file is distributed under BSD 3 clause and LGPL2.1 (dual license)
// SPDX License Identifier: BSD-3-Clause
// SPDX License Identifier: LGPL-2.1-only
//
// The entire notice above must be reproduced on all authorized copies.
//
// Description :
//-----------------------------------------------------------------------------
#include <string.h>
#include <stdarg.h>
#include <errno.h>
#include <unistd.h>
#include <sys/eventfd.h>
#include "main_helper.h"
#include "nc_utils.h"
#include <pthread.h>
extern YuvFeederImpl loaderYuvFeederImpl;
extern YuvFeederImpl cfbcYuvFeederImpl;
BOOL loaderYuvFeeder_Create(
YuvFeederImpl *impl,
const char* path,
Uint32 packed,
Uint32 fbStride,
Uint32 fbHeight
);
BOOL loaderYuvFeeder_Destory(
YuvFeederImpl *impl
);
BOOL loaderYuvFeeder_Feed(
YuvFeederImpl* impl,
Int32 coreIdx,
FrameBuffer* fb,
size_t picWidth,
size_t picHeight,
Uint32 srcFbIndex,
ENC_subFrameSyncCfg *subFrameSyncConfig,
void* arg
);
BOOL loaderYuvFeeder_Configure(
YuvFeederImpl* impl,
Uint32 cmd,
YuvInfo yuv
);
BOOL cfbcYuvFeeder_Create(
YuvFeederImpl *impl,
const char* path,
Uint32 packed,
Uint32 fbStride,
Uint32 fbHeight
);
BOOL cfbcYuvFeeder_Destory(
YuvFeederImpl *impl
);
BOOL cfbcYuvFeeder_Feed(
YuvFeederImpl* impl,
Int32 coreIdx,
FrameBuffer* fb,
size_t picWidth,
size_t picHeight,
Uint32 srcFbIndex,
ENC_subFrameSyncCfg *subFrameSyncConfig,
void* arg
);
BOOL cfbcYuvFeeder_Configure(
YuvFeederImpl* impl,
Uint32 cmd,
YuvInfo yuv
);
static BOOL yuvYuvFeeder_Create(
YuvFeederImpl *impl,
const char* path __attribute__((unused)),
Uint32 packed,
Uint32 fbStride,
Uint32 fbHeight)
{
yuvContext* ctx;
osal_file_t fp = NULL;
Uint8* pYuv;
if ( packed == 1 )
pYuv = (Uint8*)osal_malloc(fbStride*fbHeight*3*2*2);//packed, unsigned short
else
pYuv = (Uint8*)osal_malloc(fbStride*fbHeight*3*2);//unsigned short
if ((ctx=(yuvContext*)osal_malloc(sizeof(yuvContext))) == NULL) {
osal_free(pYuv);
osal_fclose(fp);
return FALSE;
}
osal_memset(ctx, 0, sizeof(yuvContext));
ctx->fp = fp;
ctx->pYuv = pYuv;
impl->context = ctx;
return TRUE;
}
static BOOL yuvYuvFeeder_Destory(
YuvFeederImpl *impl
)
{
yuvContext* ctx = (yuvContext*)impl->context;
osal_free(ctx->pYuv);
osal_free(ctx);
return TRUE;
}
static BOOL yuvYuvFeeder_Mqueue(
YuvFeederImpl* impl,
Int32 coreIdx,
FrameBuffer* fb,
size_t picWidth,
size_t picHeight,
Uint32 srcFbIndex,
ENC_subFrameSyncCfg *subFrameSyncConfig,
void* arg
)
{
yuvContext* ctx = (yuvContext*)impl->context;
Uint8* pYuv = ctx->pYuv;
size_t frameSize;
size_t frameSizeY;
size_t frameSizeC;
Int32 bitdepth=0;
Int32 yuv3p4b=0;
Int32 packedFormat=0;
Uint32 outWidth=0;
Uint32 outHeight=0;
Uint32 subFrameSyncSrcWriteMode = subFrameSyncConfig->subFrameSyncSrcWriteMode;
BOOL subFrameSyncEn = subFrameSyncConfig->subFrameSyncOn;
Uint32 writeSrcLine = subFrameSyncSrcWriteMode & ~REMAIN_SRC_DATA_WRITE;
Uint8* receive_buf = NULL;
CODEC_ERR_STATE codec_state = CODEC_SUCCESS;
if ( subFrameSyncEn == TRUE && subFrameSyncSrcWriteMode == SRC_0LINE_WRITE ) {
return TRUE;
}
CalcYuvSize(fb->format, (Int32)picWidth, (Int32)picHeight, fb->cbcrInterleave, &frameSizeY, &frameSizeC, &frameSize, &bitdepth, &packedFormat, &yuv3p4b);
//Already wrote in SRC_XXXLINE_WRITE mode
if ( subFrameSyncEn == TRUE && subFrameSyncSrcWriteMode & REMAIN_SRC_DATA_WRITE && writeSrcLine == picHeight) {
return TRUE;
}
if (fb->mapType == LINEAR_FRAME_MAP ) {
outWidth = (Uint32)((yuv3p4b&&packedFormat==0) ? ((picWidth+31)/32)*32 : picWidth);
outHeight = (Uint32)((yuv3p4b) ? ((picHeight+7)/8)*8 : picHeight);
if ( yuv3p4b && packedFormat) {
outWidth = (Uint32)(((picWidth*2)+2)/3*4);
}
else if(packedFormat) {
outWidth *= 2; // 8bit packed mode(YUYV) only. (need to add 10bit cases later)
if (bitdepth != 0) // 10bit packed
outWidth *= 2;
}
#ifdef CNM_FPGA_VU440_INTERFACE
LoadYuvImageBurstFormat(coreIdx, pYuv, outWidth, outHeight, fb, ctx->srcPlanar);
#else
int32 auto_free = 0;
// VLOG(INFO, "[%s:%d] [before] nc_receive_buf_to_encode() ...............\n", __FUNCTION__, __LINE__);
if((codec_state = nc_receive_buf_to_encode(&receive_buf, &auto_free)) == CODEC_SUCCESS) {
if (!receive_buf) {
return FALSE;
}
LoadYuvImageByYCbCrLine(impl->handle, coreIdx, receive_buf, outWidth, outHeight, fb, arg, subFrameSyncConfig, srcFbIndex);
if (auto_free && receive_buf) {
free (receive_buf);
}
} else {
printf("nc_receive_buf_to_encode failure ... err state : %d \n", codec_state);
return FALSE;
}
// VLOG(INFO, "[%s:%d] [after end] nc_receive_buf_to_encode() ...............\n", __FUNCTION__, __LINE__);
#endif
}
else {
TiledMapConfig mapConfig;
osal_memset((void*)&mapConfig, 0x00, sizeof(TiledMapConfig));
if (arg != NULL) {
osal_memcpy((void*)&mapConfig, arg, sizeof(TiledMapConfig));
}
LoadTiledImageYuvBurst(impl->handle, coreIdx, pYuv, picWidth, picHeight, fb, mapConfig);
}
return TRUE;
}
static BOOL yuvYuvFeeder_Configure(
YuvFeederImpl* impl,
Uint32 cmd,
YuvInfo yuv
)
{
yuvContext* ctx = (yuvContext*)impl->context;
UNREFERENCED_PARAMETER(cmd);
ctx->fbStride = yuv.srcStride;
ctx->cbcrInterleave = yuv.cbcrInterleave;
ctx->srcPlanar = yuv.srcPlanar;
return TRUE;
}
YuvFeederImpl yuvYuvFeederImpl = {
NULL,
yuvYuvFeeder_Create,
NULL,
NULL,
yuvYuvFeeder_Destory,
yuvYuvFeeder_Configure,
NULL
};
/*lint -esym(438, ap) */
YuvFeeder YuvFeeder_Create(
Uint32 type,
const char* srcFilePath,
YuvInfo yuvInfo
)
{
AbstractYuvFeeder *feeder;
YuvFeederImpl *impl;
BOOL success = FALSE;
if (srcFilePath == NULL) {
VLOG(ERR, "%s:%d src path is NULL\n", __FUNCTION__, __LINE__);
return NULL;
}
// Create YuvFeeder for type.
switch (type) {
case SOURCE_YUV:
impl = (YuvFeederImpl*)osal_malloc(sizeof(YuvFeederImpl));
impl->Create = yuvYuvFeeder_Create;
impl->Mqueue = yuvYuvFeeder_Mqueue;
impl->Destroy = yuvYuvFeeder_Destory;
impl->Configure = yuvYuvFeeder_Configure;
if ((success=impl->Create(impl, srcFilePath, yuvInfo.packedFormat, yuvInfo.srcStride, yuvInfo.srcHeight)) == TRUE) {
impl->Configure(impl, 0, yuvInfo);
}
break;
case SOURCE_YUV_WITH_LOADER:
impl = (YuvFeederImpl*)osal_malloc(sizeof(YuvFeederImpl));
impl->Create = loaderYuvFeeder_Create;
impl->Dequeue = loaderYuvFeeder_Feed;
impl->Destroy = loaderYuvFeeder_Destory;
impl->Configure = loaderYuvFeeder_Configure;
if ((success=impl->Create(impl, srcFilePath, yuvInfo.packedFormat, yuvInfo.srcStride, yuvInfo.srcHeight)) == TRUE) {
impl->Configure(impl, 0, yuvInfo);
}
break;
default:
VLOG(ERR, "%s:%d Unknown YuvFeeder Type\n", __FUNCTION__, __LINE__);
return NULL;
}
if (success == FALSE)
return NULL;
feeder = (AbstractYuvFeeder*)osal_malloc(sizeof(AbstractYuvFeeder));
if ( !feeder )
return NULL;
feeder->impl = impl;
return feeder;
}
/*lint +esym(438, ap) */
BOOL YuvFeeder_Destroy(
YuvFeeder feeder
)
{
YuvFeederImpl* impl = NULL;
AbstractYuvFeeder* yuvfeeder = (AbstractYuvFeeder*)feeder;
if (yuvfeeder == NULL) {
VLOG(ERR, "%s:%d Invalid handle\n", __FUNCTION__, __LINE__);
return FALSE;
}
impl = yuvfeeder->impl;
impl->Destroy(impl);
osal_free(impl);
return TRUE;
}
BOOL YuvFeeder_Feed(
YuvFeeder feeder,
Uint32 coreIdx,
FrameBuffer* fb,
size_t picWidth,
size_t picHeight,
Uint32 srcFbIndex,
ENC_subFrameSyncCfg *subFrameSyncConfig,
void* arg
)
{
YuvFeederImpl* impl = NULL;
AbstractYuvFeeder* absFeeder = (AbstractYuvFeeder*)feeder;
Int32 ret;
if (absFeeder == NULL) {
VLOG(ERR, "%s:%d Invalid handle\n", __FUNCTION__, __LINE__);
return FALSE;
}
impl = absFeeder->impl;
nc_lock_encoding_done();
ret = impl->Mqueue(impl, coreIdx, fb, picWidth, picHeight, srcFbIndex, (ENC_subFrameSyncCfg*)arg, subFrameSyncConfig);
return ret;
}