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.
440 lines
11 KiB
440 lines
11 KiB
|
7 months ago
|
//-----------------------------------------------------------------------------
|
||
|
|
// 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 <stdio.h>
|
||
|
|
#include <stdarg.h>
|
||
|
|
#include <time.h>
|
||
|
|
#include <string.h>
|
||
|
|
|
||
|
|
#include "main_helper.h"
|
||
|
|
|
||
|
|
typedef struct {
|
||
|
|
FeedingMethod method;
|
||
|
|
Uint8* remainData;
|
||
|
|
Uint32 remainDataSize;
|
||
|
|
void* actualFeeder;
|
||
|
|
Uint32 coreIdx;
|
||
|
|
Uint32 room;
|
||
|
|
Uint32 fillingMode;
|
||
|
|
BOOL eos;
|
||
|
|
DecHandle decHandle;
|
||
|
|
EndianMode endian;
|
||
|
|
BSFeederHook observer;
|
||
|
|
void* observerArg;
|
||
|
|
vpu_buffer_t bitBuffer;
|
||
|
|
int sequenceHeaderSize;
|
||
|
|
} BitstreamFeeder;
|
||
|
|
|
||
|
|
static void BitstreamFeeder_DummyObserver(
|
||
|
|
void* handle,
|
||
|
|
void* es,
|
||
|
|
Uint32 size,
|
||
|
|
void* arg
|
||
|
|
)
|
||
|
|
{
|
||
|
|
UNREFERENCED_PARAMETER(handle);
|
||
|
|
UNREFERENCED_PARAMETER(es);
|
||
|
|
UNREFERENCED_PARAMETER(size);
|
||
|
|
UNREFERENCED_PARAMETER(arg);
|
||
|
|
}
|
||
|
|
|
||
|
|
extern void* BSFeederFixedSize_Create(
|
||
|
|
const char* path,
|
||
|
|
CodStd codecId
|
||
|
|
);
|
||
|
|
|
||
|
|
extern BOOL BSFeederFixedSize_Destroy(
|
||
|
|
void* feeder
|
||
|
|
);
|
||
|
|
|
||
|
|
extern Int32 BSFeederFixedSize_Act(
|
||
|
|
void* feeder,
|
||
|
|
BSChunk* chunk
|
||
|
|
);
|
||
|
|
|
||
|
|
extern BOOL BSFeederFixedSize_Rewind(
|
||
|
|
void* feeder
|
||
|
|
);
|
||
|
|
|
||
|
|
extern void BSFeederFixedSize_SetFeedingSize(
|
||
|
|
void* feeder,
|
||
|
|
Uint32 feedingSize
|
||
|
|
);
|
||
|
|
|
||
|
|
extern void* BSFeederFrameSize_Create(
|
||
|
|
const char* path,
|
||
|
|
CodStd codec
|
||
|
|
);
|
||
|
|
|
||
|
|
extern BOOL BSFeederFrameSize_Destroy(
|
||
|
|
void* feeder
|
||
|
|
);
|
||
|
|
|
||
|
|
extern Int32 BSFeederFrameSize_Act(
|
||
|
|
void* feeder,
|
||
|
|
BSChunk* packet
|
||
|
|
);
|
||
|
|
|
||
|
|
extern BOOL BSFeederFrameSize_Rewind(
|
||
|
|
void* feeder
|
||
|
|
);
|
||
|
|
|
||
|
|
extern void* BSFeederSizePlusEs_Create(
|
||
|
|
const char* path,
|
||
|
|
CodStd codecId
|
||
|
|
);
|
||
|
|
|
||
|
|
extern BOOL BSFeederSizePlusEs_Destroy(
|
||
|
|
void* feeder
|
||
|
|
);
|
||
|
|
|
||
|
|
extern Int32 BSFeederSizePlusEs_Act(
|
||
|
|
void* feeder,
|
||
|
|
BSChunk* chunk
|
||
|
|
);
|
||
|
|
|
||
|
|
extern BOOL BSFeederSizePlusEs_Rewind(
|
||
|
|
void* feeder
|
||
|
|
);
|
||
|
|
|
||
|
|
extern Int32 BSFeederFrameSize_GetStandard(
|
||
|
|
void* feeder
|
||
|
|
);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Abstract Bitstream Feeader Functions
|
||
|
|
*/
|
||
|
|
void* BitstreamFeeder_Create(
|
||
|
|
Uint32 coreIdx,
|
||
|
|
const char* path,
|
||
|
|
CodStd codecId,
|
||
|
|
FeedingMethod method,
|
||
|
|
EndianMode endian
|
||
|
|
)
|
||
|
|
{
|
||
|
|
/*lint -esym(438, ap) */
|
||
|
|
BitstreamFeeder* handle = NULL;
|
||
|
|
void* feeder = NULL;
|
||
|
|
|
||
|
|
switch (method) {
|
||
|
|
case FEEDING_METHOD_FIXED_SIZE:
|
||
|
|
feeder = BSFeederFixedSize_Create(path, codecId);
|
||
|
|
break;
|
||
|
|
case FEEDING_METHOD_SIZE_PLUS_ES:
|
||
|
|
feeder = BSFeederSizePlusEs_Create(path, codecId);
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
feeder = NULL;
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (feeder != NULL) {
|
||
|
|
if ((handle=(BitstreamFeeder*)osal_malloc(sizeof(BitstreamFeeder))) == NULL) {
|
||
|
|
VLOG(ERR, "%s:%d Failed to allocate memory\n", __FUNCTION__, __LINE__);
|
||
|
|
return NULL;
|
||
|
|
}
|
||
|
|
handle->actualFeeder = feeder;
|
||
|
|
handle->method = method;
|
||
|
|
handle->remainData = NULL;
|
||
|
|
handle->remainDataSize = 0;
|
||
|
|
handle->fillingMode = (method == FEEDING_METHOD_FIXED_SIZE) ? BSF_FILLING_RINGBUFFER : BSF_FILLING_LINEBUFFER;
|
||
|
|
handle->eos = FALSE;
|
||
|
|
handle->observer = (BSFeederHook)BitstreamFeeder_DummyObserver;
|
||
|
|
handle->observerArg = NULL;
|
||
|
|
handle->endian = endian;
|
||
|
|
handle->coreIdx = coreIdx;
|
||
|
|
}
|
||
|
|
|
||
|
|
return handle;
|
||
|
|
/*lint +esym(438, ap) */
|
||
|
|
}
|
||
|
|
|
||
|
|
void BitstreamFeeder_SetFillMode(
|
||
|
|
BSFeeder feeder,
|
||
|
|
Uint32 mode
|
||
|
|
)
|
||
|
|
{
|
||
|
|
BitstreamFeeder* bsf = (BitstreamFeeder*)feeder;
|
||
|
|
|
||
|
|
switch (mode) {
|
||
|
|
case BSF_FILLING_AUTO:
|
||
|
|
bsf->fillingMode = (bsf->method == FEEDING_METHOD_FIXED_SIZE) ? BSF_FILLING_RINGBUFFER : BSF_FILLING_LINEBUFFER;
|
||
|
|
break;
|
||
|
|
case BSF_FILLING_RINGBUFFER:
|
||
|
|
case BSF_FILLING_LINEBUFFER:
|
||
|
|
case BSF_FILLING_RINGBUFFER_WITH_ENDFLAG:
|
||
|
|
bsf->fillingMode = mode;
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
VLOG(INFO, "%s Not supported mode %d\n", __FUNCTION__, mode);
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
BOOL BitstreamFeeder_SetFeedingSize(
|
||
|
|
BSFeeder feeder,
|
||
|
|
Uint32 size
|
||
|
|
)
|
||
|
|
{
|
||
|
|
BitstreamFeeder* bsf = (BitstreamFeeder*)feeder;
|
||
|
|
BOOL ret = FALSE;
|
||
|
|
|
||
|
|
if (bsf->method == FEEDING_METHOD_FIXED_SIZE) {
|
||
|
|
BSFeederFixedSize_SetFeedingSize(bsf->actualFeeder, size);
|
||
|
|
ret = TRUE;
|
||
|
|
}
|
||
|
|
|
||
|
|
return ret;
|
||
|
|
}
|
||
|
|
|
||
|
|
Uint32 BitstreamFeeder_Act(
|
||
|
|
BSFeeder feeder,
|
||
|
|
vpu_buffer_t* bsBuffer,
|
||
|
|
PhysicalAddress wrPtr,
|
||
|
|
Uint32 room,
|
||
|
|
PhysicalAddress* newWrPtr
|
||
|
|
)
|
||
|
|
{
|
||
|
|
BitstreamFeeder* bsf = (BitstreamFeeder*)feeder;
|
||
|
|
Int32 feedingSize = 0;
|
||
|
|
BSChunk chunk;
|
||
|
|
EndianMode endian;
|
||
|
|
|
||
|
|
memset(&chunk, 0, sizeof(BSChunk));
|
||
|
|
|
||
|
|
if (bsf == NULL) {
|
||
|
|
VLOG(ERR, "%s:%d Null handle\n", __FUNCTION__, __LINE__);
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
endian = bsf->endian;
|
||
|
|
|
||
|
|
if (bsf->remainData == NULL) {
|
||
|
|
chunk.size = bsBuffer->size;
|
||
|
|
chunk.data = osal_malloc(chunk.size);
|
||
|
|
chunk.eos = FALSE;
|
||
|
|
if (chunk.data == NULL) {
|
||
|
|
VLOG(ERR, "%s:%d failed to allocate memory\n", __FUNCTION__, __LINE__);
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
switch (bsf->method) {
|
||
|
|
case FEEDING_METHOD_FIXED_SIZE:
|
||
|
|
feedingSize = BSFeederFixedSize_Act(bsf->actualFeeder, &chunk);
|
||
|
|
break;
|
||
|
|
case FEEDING_METHOD_SIZE_PLUS_ES:
|
||
|
|
feedingSize = BSFeederSizePlusEs_Act(bsf->actualFeeder, &chunk);
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
VLOG(ERR, "%s:%d Invalid method(%d)\n", __FUNCTION__, __LINE__, bsf->method);
|
||
|
|
osal_free(chunk.data);
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
chunk.data = bsf->remainData;
|
||
|
|
feedingSize = bsf->remainDataSize;
|
||
|
|
}
|
||
|
|
|
||
|
|
bsf->observer((void*)bsf, chunk.data, feedingSize, bsf->observerArg);
|
||
|
|
|
||
|
|
if (feedingSize < 0) {
|
||
|
|
VLOG(ERR, "feeding size is negative value: %d\n", feedingSize);
|
||
|
|
osal_free(chunk.data);
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (feedingSize > 0) {
|
||
|
|
Uint32 rightSize=0, leftSize=feedingSize;
|
||
|
|
PhysicalAddress base = bsBuffer->phys_addr;
|
||
|
|
Uint32 size = bsBuffer->size;
|
||
|
|
|
||
|
|
if ((Int32)room < feedingSize) {
|
||
|
|
bsf->remainData = (Uint8*)chunk.data;
|
||
|
|
bsf->remainDataSize = feedingSize;
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (bsf->fillingMode == BSF_FILLING_RINGBUFFER || bsf->fillingMode == BSF_FILLING_RINGBUFFER_WITH_ENDFLAG) {
|
||
|
|
if ((wrPtr+feedingSize) >= (base+size)) {
|
||
|
|
PhysicalAddress endAddr = base+size;
|
||
|
|
rightSize = endAddr-wrPtr;
|
||
|
|
leftSize = (wrPtr+feedingSize) - endAddr;
|
||
|
|
if (rightSize > 0) {
|
||
|
|
VpuWriteMem(bsf->coreIdx, wrPtr, (unsigned char*)chunk.data, rightSize, (int)endian);
|
||
|
|
// VLOG(TRACE, "<%s:%d> WRPTR: %p SIZE: %x\n", __FUNCTION__, __LINE__, wrPtr, rightSize);
|
||
|
|
}
|
||
|
|
wrPtr = base;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
VpuWriteMem(bsf->coreIdx, wrPtr, (unsigned char*)chunk.data+rightSize, leftSize, (int)endian);
|
||
|
|
*newWrPtr = wrPtr + leftSize;
|
||
|
|
}
|
||
|
|
|
||
|
|
bsf->eos = chunk.eos;
|
||
|
|
bsf->sequenceHeaderSize = chunk.seqHeaderSize;
|
||
|
|
osal_free(chunk.data);
|
||
|
|
|
||
|
|
bsf->remainData = NULL;
|
||
|
|
bsf->remainDataSize = 0;
|
||
|
|
|
||
|
|
return feedingSize;
|
||
|
|
}
|
||
|
|
|
||
|
|
BOOL BitstreamFeeder_IsEos(
|
||
|
|
BSFeeder feeder
|
||
|
|
)
|
||
|
|
{
|
||
|
|
BitstreamFeeder* bsf = (BitstreamFeeder*)feeder;
|
||
|
|
|
||
|
|
if (bsf == NULL) {
|
||
|
|
VLOG(ERR, "%s:%d Null handle\n", __FUNCTION__, __LINE__);
|
||
|
|
return FALSE;
|
||
|
|
}
|
||
|
|
|
||
|
|
return bsf->eos;
|
||
|
|
}
|
||
|
|
|
||
|
|
Uint32 BitstreamFeeder_GetSeqHeaderSize(
|
||
|
|
BSFeeder feeder
|
||
|
|
)
|
||
|
|
{
|
||
|
|
BitstreamFeeder* bsf = (BitstreamFeeder*)feeder;
|
||
|
|
|
||
|
|
if (bsf == NULL) {
|
||
|
|
VLOG(ERR, "%s:%d Null handle\n", __FUNCTION__, __LINE__);
|
||
|
|
return FALSE;
|
||
|
|
}
|
||
|
|
return bsf->sequenceHeaderSize;
|
||
|
|
}
|
||
|
|
|
||
|
|
Int32 BitstreamFeeder_GetStandard(
|
||
|
|
BSFeeder feeder
|
||
|
|
)
|
||
|
|
{
|
||
|
|
BitstreamFeeder* bsf = (BitstreamFeeder*)feeder;
|
||
|
|
Int32 standard = -1;
|
||
|
|
|
||
|
|
if (bsf == NULL) {
|
||
|
|
VLOG(ERR, "%s:%d Null handle\n", __FUNCTION__, __LINE__);
|
||
|
|
return FALSE;
|
||
|
|
}
|
||
|
|
|
||
|
|
switch (bsf->method) {
|
||
|
|
case FEEDING_METHOD_FIXED_SIZE:
|
||
|
|
case FEEDING_METHOD_SIZE_PLUS_ES:
|
||
|
|
default:
|
||
|
|
VLOG(ERR, "%s:%d Invalid return value (%d), method(%d)\n", __FUNCTION__, __LINE__, -1, bsf->method);
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
return standard;
|
||
|
|
}
|
||
|
|
|
||
|
|
void BitstreamFeeder_Stop(
|
||
|
|
BSFeeder feeder
|
||
|
|
)
|
||
|
|
{
|
||
|
|
BitstreamFeeder* bsf = (BitstreamFeeder*)feeder;
|
||
|
|
|
||
|
|
if (bsf == NULL) {
|
||
|
|
VLOG(ERR, "%s:%d Null handle\n", __FUNCTION__, __LINE__);
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
BOOL BitstreamFeeder_Destroy(
|
||
|
|
BSFeeder feeder
|
||
|
|
)
|
||
|
|
{
|
||
|
|
BitstreamFeeder* bsf = (BitstreamFeeder*)feeder;
|
||
|
|
|
||
|
|
if (bsf == NULL) {
|
||
|
|
return FALSE;
|
||
|
|
}
|
||
|
|
|
||
|
|
switch (bsf->method) {
|
||
|
|
case FEEDING_METHOD_FIXED_SIZE:
|
||
|
|
BSFeederFixedSize_Destroy(bsf->actualFeeder);
|
||
|
|
break;
|
||
|
|
case FEEDING_METHOD_SIZE_PLUS_ES:
|
||
|
|
BSFeederSizePlusEs_Destroy(bsf->actualFeeder);
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
VLOG(ERR, "%s:%d Invalid method(%d)\n", __FUNCTION__, __LINE__, bsf->method);
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (bsf->remainData) {
|
||
|
|
osal_free(bsf->remainData);
|
||
|
|
}
|
||
|
|
|
||
|
|
osal_free(bsf);
|
||
|
|
|
||
|
|
return TRUE;
|
||
|
|
}
|
||
|
|
|
||
|
|
BOOL BitstreamFeeder_Rewind(
|
||
|
|
BSFeeder feeder
|
||
|
|
)
|
||
|
|
{
|
||
|
|
BitstreamFeeder* bsf = (BitstreamFeeder*)feeder;
|
||
|
|
BOOL success = FALSE;
|
||
|
|
|
||
|
|
if (bsf == NULL) {
|
||
|
|
VLOG(ERR, "%s:%d handle is NULL\n", __FUNCTION__, __LINE__);
|
||
|
|
return success;
|
||
|
|
}
|
||
|
|
|
||
|
|
switch (bsf->method) {
|
||
|
|
case FEEDING_METHOD_FIXED_SIZE:
|
||
|
|
success = BSFeederFixedSize_Rewind(bsf->actualFeeder);
|
||
|
|
break;
|
||
|
|
case FEEDING_METHOD_SIZE_PLUS_ES:
|
||
|
|
success = BSFeederSizePlusEs_Rewind(bsf->actualFeeder);
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
VLOG(ERR, "%s:%d Invalid method(%d)\n", __FUNCTION__, __LINE__, bsf->method);
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (success == TRUE) {
|
||
|
|
bsf->eos = FALSE;
|
||
|
|
}
|
||
|
|
|
||
|
|
return success;
|
||
|
|
}
|
||
|
|
|
||
|
|
BOOL BitstreamFeeder_SetHook(
|
||
|
|
BSFeeder feeder,
|
||
|
|
BSFeederHook hookFunc,
|
||
|
|
void* hookArg
|
||
|
|
)
|
||
|
|
{
|
||
|
|
BitstreamFeeder* bsf = (BitstreamFeeder*)feeder;
|
||
|
|
|
||
|
|
if (bsf == NULL) {
|
||
|
|
VLOG(ERR, "%s:%d handle is NULL\n", __FUNCTION__, __LINE__);
|
||
|
|
return FALSE;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (hookFunc == NULL) {
|
||
|
|
bsf->observer = (BSFeederHook)BitstreamFeeder_DummyObserver;
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
bsf->observer = hookFunc;
|
||
|
|
}
|
||
|
|
bsf->observerArg = hookArg;
|
||
|
|
|
||
|
|
return TRUE;
|
||
|
|
}
|
||
|
|
|