1.将A27新UI文件夹重命名为CANUI 2.A272O新版本发布
This commit is contained in:
433
MXC_A27-PCB4.5-CANUI/lib/hx170dec/src/mfcapi.c
Normal file
433
MXC_A27-PCB4.5-CANUI/lib/hx170dec/src/mfcapi.c
Normal file
@ -0,0 +1,433 @@
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "FreeRTOS.h"
|
||||
#include "dwl.h"
|
||||
#include "h264decapi.h"
|
||||
#include "jpegdecapi.h"
|
||||
#include "jpegdeccontainer.h"
|
||||
#include "mfcapi.h"
|
||||
#include "mmu.h"
|
||||
#include "include/amt630hv100.h"
|
||||
#include "sysctl.h"
|
||||
#include "semphr.h"
|
||||
|
||||
#define JPEG_BUF_COUNTS 2
|
||||
|
||||
static u32 g_picDecodeNumber = 0;
|
||||
static u32 g_JpegYBusAddress = 0;
|
||||
static u32 g_JpegCbCrBusAddress = 0;
|
||||
static DWLLinearMem_t g_JpegYMemInfo[JPEG_BUF_COUNTS] = {0};
|
||||
static u32 g_JpegMemIndex = 0;
|
||||
|
||||
static void MFCSwitchIramMode(int en)
|
||||
{
|
||||
#if 0
|
||||
static SemaphoreHandle_t MfcIramMutex = NULL;
|
||||
if(!MfcIramMutex)
|
||||
MfcIramMutex = xSemaphoreCreateMutex();
|
||||
|
||||
if(MfcIramMutex)
|
||||
xSemaphoreTake(MfcIramMutex, portMAX_DELAY);
|
||||
|
||||
//0 MFC ram use as iram; 1 MFC ram use MFC REF buffer
|
||||
u32 val = readl(REGS_SYSCTL_BASE + 0x78);
|
||||
if(en)
|
||||
val |= (1<<0);
|
||||
else
|
||||
val &= ~(1<<0);
|
||||
writel(val, REGS_SYSCTL_BASE + 0x78);
|
||||
|
||||
if(MfcIramMutex)
|
||||
xSemaphoreGive(MfcIramMutex);
|
||||
#else
|
||||
portENTER_CRITICAL();
|
||||
//0 MFC ram use as iram; 1 MFC ram use MFC REF buffer
|
||||
u32 val = readl(REGS_SYSCTL_BASE + 0x78);
|
||||
if(en)
|
||||
val |= (1<<0);
|
||||
else
|
||||
val &= ~(1<<0);
|
||||
writel(val, REGS_SYSCTL_BASE + 0x78);
|
||||
portEXIT_CRITICAL();
|
||||
#endif
|
||||
}
|
||||
|
||||
int MFCH264Decode(MFCHandle *handle, DWLLinearMem_t *inBuffer, OutFrameBuffer *outBuffer)
|
||||
{
|
||||
H264DecRet ret;
|
||||
H264DecRet picRet;
|
||||
H264DecInput decIn;
|
||||
H264DecOutput decOut;
|
||||
static H264DecInfo decInfo;
|
||||
H264DecPicture decPic;
|
||||
|
||||
decIn.dataLen = inBuffer->size;
|
||||
decIn.pStream = (u8*)inBuffer->virtualAddress;
|
||||
decIn.streamBusAddress = inBuffer->busAddress;
|
||||
|
||||
do
|
||||
{
|
||||
/* Picture ID is the picture number in decoding order */
|
||||
decIn.picId = g_picDecodeNumber;
|
||||
/* decode the stream data */
|
||||
ret = H264DecDecode(handle->decInst, &decIn, &decOut);
|
||||
switch(ret)
|
||||
{
|
||||
case H264DEC_HDRS_RDY:
|
||||
/* read stream info */
|
||||
H264DecGetInfo(handle->decInst, &decInfo);
|
||||
outBuffer->codedWidth = decInfo.picWidth;
|
||||
outBuffer->codedHeight = decInfo.picHeight;
|
||||
break;
|
||||
|
||||
case H264DEC_ADVANCED_TOOLS:
|
||||
/* Arbitrary Slice Order/multiple slice groups noticed */
|
||||
/* in the stream. The decoder has to reallocate resources */
|
||||
break;
|
||||
|
||||
case H264DEC_PIC_DECODED: /* a picture was decoded */
|
||||
case H264DEC_PENDING_FLUSH:
|
||||
g_picDecodeNumber++;
|
||||
|
||||
do {
|
||||
if(outBuffer->num >= MAX_OUTFRAME_NUM)
|
||||
return 0;
|
||||
picRet = H264DecNextPicture(handle->decInst, &decPic, 0);
|
||||
if (picRet != H264DEC_PIC_RDY) {
|
||||
break;
|
||||
}
|
||||
outBuffer->buffer[outBuffer->num].keyPicture =
|
||||
decPic.isIdrPicture;
|
||||
outBuffer->buffer[outBuffer->num].yBusAddress =
|
||||
decPic.outputPictureBusAddress;
|
||||
outBuffer->buffer[outBuffer->num].pyVirAddress =
|
||||
decPic.pOutputPicture;
|
||||
outBuffer->frameWidth = decInfo.picWidth;
|
||||
outBuffer->frameHeight = decInfo.picHeight;
|
||||
outBuffer->num++;
|
||||
} while (picRet == H264DEC_PIC_RDY);
|
||||
|
||||
break;
|
||||
|
||||
case H264DEC_STRM_PROCESSED:
|
||||
/* Input stream was processed but no picture is ready */
|
||||
break;
|
||||
|
||||
case H264DEC_MEMFAIL:
|
||||
return -1;
|
||||
|
||||
default:
|
||||
/* all other cases are errors where decoding cannot continue */
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(decOut.dataLeft == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* data left undecoded */
|
||||
decIn.dataLen = decOut.dataLeft;
|
||||
decIn.pStream = decOut.pStrmCurrPos;
|
||||
decIn.streamBusAddress = decOut.strmCurrBusAddress;
|
||||
}
|
||||
}while ((ret != H264DEC_STRM_PROCESSED) && (decOut.dataLeft > 0));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int MFCJpegDecode(MFCHandle *handle, DWLLinearMem_t *inBuffer, OutFrameBuffer *outBuffer)
|
||||
{
|
||||
JpegDecInst decoder;
|
||||
JpegDecRet infoRet;
|
||||
JpegDecInput DecIn;
|
||||
JpegDecImageInfo DecImgInf;
|
||||
JpegDecOutput DecOut;
|
||||
int ret = 0;
|
||||
int i;
|
||||
|
||||
infoRet = JpegDecInit(&decoder);
|
||||
if(infoRet !=JPEGDEC_OK) {
|
||||
printf("JpegDecInit failure %d.\n", infoRet);
|
||||
return -1;
|
||||
}
|
||||
handle->decInst = (void*)decoder;
|
||||
|
||||
DecIn.decImageType = JPEGDEC_IMAGE;
|
||||
DecIn.sliceMbSet = 0;
|
||||
|
||||
DecIn.bufferSize = 0;
|
||||
DecIn.streamLength = inBuffer->size;
|
||||
DecIn.streamBuffer.busAddress= inBuffer->busAddress;
|
||||
DecIn.streamBuffer.pVirtualAddress = inBuffer->virtualAddress;
|
||||
|
||||
g_JpegYBusAddress = 0;
|
||||
|
||||
for (i = 0; i < JPEG_BUF_COUNTS; i++) {
|
||||
if(g_JpegYMemInfo[i].busAddress == 0)
|
||||
{
|
||||
if(DWLMallocLinear(((JpegDecContainer*)handle->decInst)->dwl, MAX_OUTFRAME_WIDTH*MAX_OUTFRAME_HEIGHT*2,
|
||||
&g_JpegYMemInfo[i]) == DWL_ERROR)
|
||||
{
|
||||
printf("Jpeg DWLMallocLinear y failure.\n");
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Get image information of the JFIF */
|
||||
infoRet = JpegDecGetImageInfo(handle->decInst,
|
||||
&DecIn,
|
||||
&DecImgInf);
|
||||
if(infoRet !=JPEGDEC_OK)
|
||||
{
|
||||
printf("\rJpegDecGetImageInfo failure.\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
DecIn.pictureBufferY.busAddress = g_JpegYMemInfo[g_JpegMemIndex].busAddress;
|
||||
DecIn.pictureBufferY.pVirtualAddress = g_JpegYMemInfo[g_JpegMemIndex].virtualAddress;
|
||||
DecIn.pictureBufferCbCr.busAddress = g_JpegYMemInfo[g_JpegMemIndex].busAddress + DecImgInf.outputWidth * DecImgInf.outputHeight;
|
||||
DecIn.pictureBufferCbCr.pVirtualAddress = (u32*)((u32)g_JpegYMemInfo[g_JpegMemIndex].virtualAddress +
|
||||
DecImgInf.outputWidth * DecImgInf.outputHeight);
|
||||
DecIn.pictureBufferCr.busAddress = 0;
|
||||
DecIn.pictureBufferCr.pVirtualAddress = 0;
|
||||
|
||||
g_JpegMemIndex = !g_JpegMemIndex;
|
||||
|
||||
/* Decode JFIF */
|
||||
infoRet = JpegDecDecode(handle->decInst, &DecIn, &DecOut);
|
||||
if(infoRet != JPEGDEC_FRAME_READY)
|
||||
{
|
||||
printf("\rJpegDecDecode failure, ret=%d\n", infoRet);
|
||||
if (infoRet == JPEGDEC_MEMFAIL)
|
||||
ret = -1;
|
||||
goto end;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
|
||||
outBuffer->outputFormat = DecImgInf.outputFormat;
|
||||
outBuffer->codedWidth = DecImgInf.displayWidth;
|
||||
outBuffer->codedHeight = DecImgInf.displayHeight;
|
||||
outBuffer->buffer[0].keyPicture = 1;
|
||||
g_JpegYBusAddress = DecOut.outputPictureY.busAddress;
|
||||
g_JpegCbCrBusAddress = DecOut.outputPictureCbCr.busAddress;
|
||||
if (g_JpegYBusAddress) {
|
||||
outBuffer->num = 1;
|
||||
outBuffer->buffer[0].yBusAddress = g_JpegYBusAddress;
|
||||
outBuffer->buffer[0].cbcrBusAddress = g_JpegCbCrBusAddress;
|
||||
outBuffer->buffer[0].pyVirAddress = DecOut.outputPictureY.pVirtualAddress;
|
||||
outBuffer->buffer[0].pcbcrVirAddress = DecOut.outputPictureCbCr.pVirtualAddress;
|
||||
outBuffer->frameWidth = DecImgInf.outputWidth;
|
||||
outBuffer->frameHeight = DecImgInf.outputHeight;
|
||||
}
|
||||
|
||||
end:
|
||||
|
||||
JpegDecRelease((JpegDecInst)handle->decInst);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void JpegReleaseBuffer(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i = 0; i < JPEG_BUF_COUNTS; i++) {
|
||||
if(g_JpegYMemInfo[i].virtualAddress != NULL)
|
||||
//vPortFree(g_JpegYMemInfo[i].virtualAddress - 0x10000000/4);
|
||||
vPortFree((u32 *)UNCACHED_VIRT_TO_PHT(g_JpegYMemInfo[i].virtualAddress));
|
||||
|
||||
memset(&g_JpegYMemInfo[i], 0, sizeof(g_JpegYMemInfo[i]));
|
||||
}
|
||||
}
|
||||
|
||||
int mfc_jpegdec(JpegHeaderInfo *jpegInfo)
|
||||
{
|
||||
JpegDecInst decoder;
|
||||
JpegDecRet infoRet;
|
||||
JpegDecInput DecIn;
|
||||
JpegDecImageInfo DecImgInf;
|
||||
JpegDecOutput DecOut;
|
||||
int ret = -1;
|
||||
|
||||
MFCSwitchIramMode(1);
|
||||
|
||||
infoRet = JpegDecInit(&decoder);
|
||||
if(infoRet !=JPEGDEC_OK) {
|
||||
printf("JpegDecInit failure %d.\n", infoRet);
|
||||
goto exit;
|
||||
}
|
||||
jpegInfo->handle->decInst = (void*)decoder;
|
||||
|
||||
DecIn.decImageType = JPEGDEC_IMAGE;
|
||||
DecIn.sliceMbSet = 0;
|
||||
DecIn.bufferSize = 0;
|
||||
DecIn.streamLength = jpegInfo->jpg_size;
|
||||
DecIn.streamBuffer.busAddress= jpegInfo->jpg_addr;
|
||||
DecIn.streamBuffer.pVirtualAddress = (u32 *)PHY_TO_UNCACHED_VIRT(jpegInfo->jpg_addr);
|
||||
|
||||
/* Get image information of the JFIF */
|
||||
infoRet = JpegDecGetImageInfo(jpegInfo->handle->decInst,
|
||||
&DecIn,
|
||||
&DecImgInf);
|
||||
if(infoRet !=JPEGDEC_OK)
|
||||
{
|
||||
printf("\rJpegDecGetImageInfo failure.\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
DecIn.pictureBufferY.busAddress = jpegInfo->dec_addry;
|
||||
DecIn.pictureBufferY.pVirtualAddress = (u32 *)PHY_TO_UNCACHED_VIRT(jpegInfo->dec_addry);
|
||||
DecIn.pictureBufferCbCr.busAddress = DecIn.pictureBufferY.busAddress +
|
||||
DecImgInf.outputWidth * DecImgInf.outputHeight;
|
||||
DecIn.pictureBufferCbCr.pVirtualAddress = (u32*)((u32)DecIn.pictureBufferY.pVirtualAddress +
|
||||
DecImgInf.outputWidth * DecImgInf.outputHeight);
|
||||
DecIn.pictureBufferCr.busAddress = 0;
|
||||
DecIn.pictureBufferCr.pVirtualAddress = 0;
|
||||
|
||||
/* Decode JFIF */
|
||||
infoRet = JpegDecDecode(jpegInfo->handle->decInst, &DecIn, &DecOut);
|
||||
if(infoRet != JPEGDEC_FRAME_READY)
|
||||
{
|
||||
printf("\rJpegDecDecode failure, ret=%d\n", infoRet);
|
||||
if (infoRet == JPEGDEC_MEMFAIL)
|
||||
ret = -1;
|
||||
goto end;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
|
||||
jpegInfo->dec_format = DecImgInf.outputFormat;
|
||||
jpegInfo->jpg_width = DecImgInf.displayWidth;
|
||||
jpegInfo->jpg_height = DecImgInf.displayHeight;
|
||||
if((jpegInfo->dec_format == JPEGDEC_YCbCr420_SEMIPLANAR) || (jpegInfo->dec_format == JPEGDEC_YCbCr422_SEMIPLANAR)) {
|
||||
jpegInfo->dec_width = (jpegInfo->jpg_width + 0xF) & (~0xF);
|
||||
jpegInfo->dec_height = (jpegInfo->jpg_height + 0xF) & (~0xF);
|
||||
} else {
|
||||
jpegInfo->dec_width = (jpegInfo->jpg_width + 0x7) & (~0x7);
|
||||
jpegInfo->dec_height = (jpegInfo->jpg_height + 0x7) & (~0x7);
|
||||
}
|
||||
jpegInfo->dec_addry = DecOut.outputPictureY.busAddress;
|
||||
jpegInfo->dec_addru = DecOut.outputPictureCbCr.busAddress;
|
||||
jpegInfo->dec_addrv = 0;
|
||||
|
||||
end:
|
||||
JpegDecRelease((JpegDecInst)jpegInfo->handle->decInst);
|
||||
|
||||
exit:
|
||||
MFCSwitchIramMode(0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
MFCHandle* mfc_init(int streamType)
|
||||
{
|
||||
MFCHandle *handle = NULL;
|
||||
void *decInst = NULL;
|
||||
|
||||
switch(streamType) {
|
||||
case RAW_STRM_TYPE_H264: {
|
||||
H264DecInst decoder;
|
||||
H264DecRet infoRet;
|
||||
|
||||
g_picDecodeNumber = 0;
|
||||
infoRet = H264DecInit(&decoder, 0, 0, 1);
|
||||
if(infoRet != H264DEC_OK) {
|
||||
printf("H264DecInit failure.\n");
|
||||
return NULL;
|
||||
}
|
||||
decInst = (void*)decoder;
|
||||
break;
|
||||
}
|
||||
|
||||
case RAW_STRM_TYPE_H264_NOREORDER: {
|
||||
H264DecInst decoder;
|
||||
H264DecRet infoRet;
|
||||
|
||||
g_picDecodeNumber = 0;
|
||||
infoRet = H264DecInit(&decoder, 1, 0, 1);
|
||||
if(infoRet != H264DEC_OK) {
|
||||
printf("H264DecInit failure.\n");
|
||||
return NULL;
|
||||
}
|
||||
decInst = (void*)decoder;
|
||||
break;
|
||||
}
|
||||
|
||||
case RAW_STRM_TYPE_JPEG:
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("MFCDecode unsupported format.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
handle = (MFCHandle*)pvPortMalloc(sizeof(MFCHandle));
|
||||
if (!handle)
|
||||
return NULL;
|
||||
memset(handle, 0, sizeof(MFCHandle));
|
||||
handle->decInst = decInst;
|
||||
handle->streamType = streamType;
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
int mfc_decode(MFCHandle *handle, DWLLinearMem_t *inBuffer, OutFrameBuffer *outBuffer)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (handle == NULL) {
|
||||
printf("Invalid handle.\n");
|
||||
return -1;
|
||||
}
|
||||
MFCSwitchIramMode(1);
|
||||
|
||||
outBuffer->num = 0;
|
||||
switch(handle->streamType) {
|
||||
case RAW_STRM_TYPE_H264:
|
||||
case RAW_STRM_TYPE_H264_NOREORDER:
|
||||
ret= MFCH264Decode(handle, inBuffer, outBuffer);
|
||||
break;
|
||||
case RAW_STRM_TYPE_JPEG:
|
||||
ret= MFCJpegDecode(handle, inBuffer, outBuffer);
|
||||
break;
|
||||
default:
|
||||
printf("MFCDecode unsupported format.\n");
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
MFCSwitchIramMode(0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void mfc_uninit(MFCHandle *handle)
|
||||
{
|
||||
if (handle == NULL) {
|
||||
printf("Invalid handle.\n");
|
||||
return ;
|
||||
}
|
||||
|
||||
switch(handle->streamType)
|
||||
{
|
||||
case RAW_STRM_TYPE_H264:
|
||||
case RAW_STRM_TYPE_H264_NOREORDER:
|
||||
if(handle->decInst)
|
||||
H264DecRelease((H264DecInst)handle->decInst);
|
||||
break;
|
||||
|
||||
case RAW_STRM_TYPE_JPEG:
|
||||
JpegReleaseBuffer();
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("MFCRelease unsupported format.\n");
|
||||
break;
|
||||
}
|
||||
|
||||
vPortFree(handle);
|
||||
}
|
Reference in New Issue
Block a user