/*------------------------------------------------------------------------------
|
-- --
|
-- This software is confidential and proprietary and may be used --
|
-- only as expressly authorized by a licensing agreement from --
|
-- --
|
-- Rockchip Products . --
|
-- --
|
-- (C) COPYRIGHT 2014 ROCKCHIP PRODUCTS --
|
-- ALL RIGHTS RESERVED --
|
-- --
|
-- The entire notice above must be reproduced --
|
-- on all copies and should not be removed. --
|
-- --
|
--------------------------------------------------------------------------------
|
--
|
-- Description : SW Jpeg Decoder
|
--
|
------------------------------------------------------------------------------
|
--
|
--
|
--
|
|
------------------------------------------------------------------------------*/
|
/*------------------------------------------------------------------------------
|
|
Table of contents
|
|
1. Include headers
|
2. External compiler flags
|
3. Module defines
|
4. Local function prototypes
|
5. Functions
|
- JpegDecClearStructs
|
- JpegDecInitHW
|
- JpegDecAllocateResidual
|
- JpegDecWriteTables
|
- JpegRefreshRegs
|
- JpegFlushRegs
|
|
------------------------------------------------------------------------------*/
|
|
/*------------------------------------------------------------------------------
|
1. Include headers
|
------------------------------------------------------------------------------*/
|
#include <stdio.h>
|
#include <assert.h>
|
#include <stdlib.h>
|
#include <string.h>
|
#include <time.h>
|
|
#include "vpu_type.h"
|
#include "jpegdeccontainer.h"
|
#include "jpegdecapi.h"
|
#include "jpegdecmarkers.h"
|
#include "jpegdecutils.h"
|
#include "jpegdechdrs.h"
|
#include "jpegdecscan.h"
|
#include "jpegregdrv.h"
|
#include "jpegdecinternal.h"
|
#include "dwl.h"
|
#include "deccfg.h"
|
#define LOG_TAG "JPEG_DEC"
|
|
|
#include "vpu.h"
|
#include "hw_jpegdecapi.h"
|
#include "allocator_drm.h"
|
|
#define ALOGV printf
|
#define ALOGD printf
|
#define ALOGI printf
|
#define ALOGW printf
|
#define ALOGE printf
|
|
/*------------------------------------------------------------------------------
|
2. External compiler flags
|
--------------------------------------------------------------------------------
|
|
--------------------------------------------------------------------------------
|
3. Module defines
|
------------------------------------------------------------------------------*/
|
|
static const RK_U8 zzOrder[64] = {
|
0, 1, 8, 16, 9, 2, 3, 10, 17, 24, 32, 25, 18, 11, 4, 5,
|
12, 19, 26, 33, 40, 48, 41, 34, 27, 20, 13, 6, 7, 14, 21, 28,
|
35, 42, 49, 56, 57, 50, 43, 36, 29, 22, 15, 23, 30, 37, 44, 51,
|
58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63
|
};
|
|
#define JPEGDEC_SLICE_START_VALUE 0
|
#define JPEGDEC_VLC_LEN_START_REG 134
|
#define JPEGDEC_VLC_LEN_END_REG 147
|
|
#ifdef PJPEG_COMPONENT_TRACE
|
extern RK_U32 pjpegComponentId;
|
extern RK_U32 *pjpegCoeffBase;
|
extern RK_U32 pjpegCoeffSize;
|
|
#define TRACE_COMPONENT_ID(id) pjpegComponentId = id
|
#else
|
#define TRACE_COMPONENT_ID(id)
|
#endif
|
|
/*------------------------------------------------------------------------------
|
4. Local function prototypes
|
------------------------------------------------------------------------------*/
|
static void JpegDecWriteTables(JpegDecContainer * pJpegDecCont);
|
static void JpegDecWriteTablesNonInterleaved(JpegDecContainer * pJpegDecCont);
|
static void JpegDecWriteTablesProgressive(JpegDecContainer * pJpegDecCont);
|
static void JpegDecChromaTableSelectors(JpegDecContainer * pJpegDecCont);
|
static void JpegDecSetHwStrmParams(JpegDecContainer * pJpegDecCont);
|
static void JpegDecWriteLenBits(JpegDecContainer * pJpegDecCont);
|
static void JpegDecWriteLenBitsNonInterleaved(JpegDecContainer * pJpegDecCont);
|
static void JpegDecWriteLenBitsProgressive(JpegDecContainer * pJpegDecCont);
|
|
/*------------------------------------------------------------------------------
|
5. Functions
|
------------------------------------------------------------------------------*/
|
|
/*------------------------------------------------------------------------------
|
|
Function name: JpegDecClearStructs
|
|
Functional description:
|
handles the initialisation of jpeg decoder data structure
|
|
Inputs:
|
|
Outputs:
|
Returns OK when successful, NOK in case unknown message type is
|
asked
|
|
------------------------------------------------------------------------------*/
|
void JpegDecClearStructs(JpegDecContainer * pJpegDecCont)
|
{
|
RK_U32 i;
|
|
ASSERT(pJpegDecCont);
|
|
/* stream pointers */
|
pJpegDecCont->stream.thumbnail = 0;
|
pJpegDecCont->stream.streamBus = 0;
|
pJpegDecCont->stream.pStartOfStream = NULL;
|
pJpegDecCont->stream.pCurrPos = NULL;
|
pJpegDecCont->stream.bitPosInByte = 0;
|
pJpegDecCont->stream.streamLength = 0;
|
pJpegDecCont->stream.readBits = 0;
|
pJpegDecCont->stream.appnFlag = 0;
|
pJpegDecCont->stream.returnSosMarker = 0;
|
|
/* output image pointers and variables */
|
pJpegDecCont->image.pStartOfImage = NULL;
|
pJpegDecCont->image.pLum = NULL;
|
pJpegDecCont->image.pCr = NULL;
|
pJpegDecCont->image.pCb = NULL;
|
pJpegDecCont->image.headerReady = 0;
|
pJpegDecCont->image.imageReady = 0;
|
pJpegDecCont->image.ready = 0;
|
pJpegDecCont->image.size = 0;
|
pJpegDecCont->image.sizeLuma = 0;
|
pJpegDecCont->image.sizeChroma = 0;
|
for (i = 0; i < MAX_NUMBER_OF_COMPONENTS; i++) {
|
pJpegDecCont->image.columns[i] = 0;
|
pJpegDecCont->image.pixelsPerRow[i] = 0;
|
}
|
|
/* frame info */
|
pJpegDecCont->frame.Lf = 0;
|
pJpegDecCont->frame.P = 0;
|
pJpegDecCont->frame.Y = 0;
|
pJpegDecCont->frame.X = 0;
|
pJpegDecCont->frame.hwY = 0;
|
pJpegDecCont->frame.hwX = 0;
|
pJpegDecCont->frame.Nf = 0; /* Number of components in frame */
|
pJpegDecCont->frame.codingType = 0;
|
pJpegDecCont->frame.numMcuInFrame = 0;
|
pJpegDecCont->frame.numMcuInRow = 0;
|
pJpegDecCont->frame.mcuNumber = 0;
|
pJpegDecCont->frame.Ri = 0;
|
pJpegDecCont->frame.row = 0;
|
pJpegDecCont->frame.col = 0;
|
pJpegDecCont->frame.driPeriod = 0;
|
pJpegDecCont->frame.block = 0;
|
pJpegDecCont->frame.cIndex = 0;
|
pJpegDecCont->frame.bufferBus = 0;
|
pJpegDecCont->frame.pBuffer = NULL;
|
pJpegDecCont->frame.pBufferCb = NULL;
|
pJpegDecCont->frame.pBufferCr = NULL;
|
pJpegDecCont->frame.pTableBase.vir_addr = NULL;
|
pJpegDecCont->frame.pTableBase.phy_addr = 0;
|
|
/* asic buffer */
|
pJpegDecCont->asicBuff.outLumaBuffer.vir_addr = NULL;
|
pJpegDecCont->asicBuff.outChromaBuffer.vir_addr = NULL;
|
pJpegDecCont->asicBuff.outChromaBuffer2.vir_addr = NULL;
|
pJpegDecCont->asicBuff.outLumaBuffer.phy_addr = 0;
|
pJpegDecCont->asicBuff.outChromaBuffer.phy_addr = 0;
|
pJpegDecCont->asicBuff.outChromaBuffer2.phy_addr = 0;
|
pJpegDecCont->asicBuff.outLumaBuffer.offset = 0;
|
pJpegDecCont->asicBuff.outChromaBuffer.offset = 0;
|
pJpegDecCont->asicBuff.outChromaBuffer2.offset = 0;
|
|
/* pp instance */
|
pJpegDecCont->ppInstance = NULL;
|
pJpegDecCont->ppControl.usePipeline = 0;
|
|
/* asic running flag */
|
pJpegDecCont->asicRunning = 0;
|
|
/* resolution */
|
pJpegDecCont->minSupportedWidth = 0;
|
pJpegDecCont->minSupportedHeight = 0;
|
pJpegDecCont->maxSupportedWidth = 0;
|
pJpegDecCont->maxSupportedHeight = 0;
|
pJpegDecCont->maxSupportedPixelAmount = 0;
|
pJpegDecCont->maxSupportedSliceSize = 0;
|
|
/* out bus tmp */
|
pJpegDecCont->info.outLuma.vir_addr = NULL;
|
pJpegDecCont->info.outChroma.vir_addr = NULL;
|
pJpegDecCont->info.outChroma2.vir_addr = NULL;
|
|
/* user allocated addresses */
|
pJpegDecCont->info.givenOutLuma.vir_addr = NULL;
|
pJpegDecCont->info.givenOutChroma.vir_addr = NULL;
|
pJpegDecCont->info.givenOutChroma2.vir_addr = NULL;
|
|
/* image handling info */
|
pJpegDecCont->info.sliceHeight = 0;
|
pJpegDecCont->info.amountOfQTables = 0;
|
pJpegDecCont->info.yCbCrMode = 0;
|
pJpegDecCont->info.yCbCr422 = 0;
|
pJpegDecCont->info.column = 0;
|
pJpegDecCont->info.X = 0;
|
pJpegDecCont->info.Y = 0;
|
pJpegDecCont->info.memSize = 0;
|
pJpegDecCont->info.SliceCount = 0;
|
pJpegDecCont->info.SliceMBCutValue = 0;
|
pJpegDecCont->info.pipeline = 0;
|
pJpegDecCont->info.userAllocMem = 0;
|
pJpegDecCont->info.sliceStartCount = 0;
|
pJpegDecCont->info.amountOfSlices = 0;
|
pJpegDecCont->info.noSliceIrqForUser = 0;
|
pJpegDecCont->info.SliceReadyForPause = 0;
|
pJpegDecCont->info.sliceLimitReached = 0;
|
pJpegDecCont->info.sliceMbSetValue = 0;
|
pJpegDecCont->info.timeout = (RK_U32) DEC_RK70_TIMEOUT_LENGTH;
|
pJpegDecCont->info.rlcMode = 0; /* JPEG always in VLC mode == 0 */
|
pJpegDecCont->info.lumaPos = 0;
|
pJpegDecCont->info.chromaPos = 0;
|
pJpegDecCont->info.fillRight = 0;
|
pJpegDecCont->info.fillBottom = 0;
|
pJpegDecCont->info.streamEnd = 0;
|
pJpegDecCont->info.streamEndFlag = 0;
|
pJpegDecCont->info.inputBufferEmpty = 0;
|
pJpegDecCont->info.inputStreaming = 0;
|
pJpegDecCont->info.inputBufferLen = 0;
|
pJpegDecCont->info.decodedStreamLen = 0;
|
pJpegDecCont->info.init = 0;
|
pJpegDecCont->info.initThumb = 0;
|
pJpegDecCont->info.initBufferSize = 0;
|
|
/* progressive */
|
pJpegDecCont->info.nonInterleaved = 0;
|
pJpegDecCont->info.componentId = 0;
|
pJpegDecCont->info.operationType = 0;
|
pJpegDecCont->info.operationTypeThumb = 0;
|
pJpegDecCont->info.progressiveScanReady = 0;
|
pJpegDecCont->info.nonInterleavedScanReady = 0;
|
pJpegDecCont->info.pCoeffBase.vir_addr = NULL;
|
pJpegDecCont->info.pCoeffBase.phy_addr = 0;
|
pJpegDecCont->info.allocated = 0;
|
pJpegDecCont->info.yCbCrModeOrig = 0;
|
pJpegDecCont->info.getInfoYCbCrMode = 0;
|
pJpegDecCont->info.progressiveFinish = 0;
|
pJpegDecCont->info.pfCompId = 0;
|
for (i = 0; i < MAX_NUMBER_OF_COMPONENTS; i++)
|
pJpegDecCont->info.pfNeeded[i] = 0;
|
pJpegDecCont->info.tmpStrm.vir_addr = NULL;
|
|
for (i = 0; i < MAX_NUMBER_OF_COMPONENTS; i++) {
|
pJpegDecCont->info.components[i] = 0;
|
pJpegDecCont->info.pred[i] = 0;
|
pJpegDecCont->info.dcRes[i] = 0;
|
pJpegDecCont->frame.numBlocks[i] = 0;
|
pJpegDecCont->frame.blocksPerRow[i] = 0;
|
pJpegDecCont->frame.useAcOffset[i] = 0;
|
pJpegDecCont->frame.component[i].C = 0;
|
pJpegDecCont->frame.component[i].H = 0;
|
pJpegDecCont->frame.component[i].V = 0;
|
pJpegDecCont->frame.component[i].Tq = 0;
|
}
|
|
/* scan info */
|
pJpegDecCont->scan.Ls = 0;
|
pJpegDecCont->scan.Ns = 0;
|
pJpegDecCont->scan.Ss = 0;
|
pJpegDecCont->scan.Se = 0;
|
pJpegDecCont->scan.Ah = 0;
|
pJpegDecCont->scan.Al = 0;
|
pJpegDecCont->scan.index = 0;
|
pJpegDecCont->scan.numIdctRows = 0;
|
|
for (i = 0; i < MAX_NUMBER_OF_COMPONENTS; i++) {
|
pJpegDecCont->scan.Cs[i] = 0;
|
pJpegDecCont->scan.Td[i] = 0;
|
pJpegDecCont->scan.Ta[i] = 0;
|
pJpegDecCont->scan.pred[i] = 0;
|
}
|
|
/* huffman table lengths */
|
pJpegDecCont->vlc.acTable0.tableLength = 0;
|
pJpegDecCont->vlc.acTable1.tableLength = 0;
|
pJpegDecCont->vlc.acTable2.tableLength = 0;
|
pJpegDecCont->vlc.acTable3.tableLength = 0;
|
|
pJpegDecCont->vlc.dcTable0.tableLength = 0;
|
pJpegDecCont->vlc.dcTable1.tableLength = 0;
|
pJpegDecCont->vlc.dcTable2.tableLength = 0;
|
pJpegDecCont->vlc.dcTable3.tableLength = 0;
|
|
/* Restart interval */
|
pJpegDecCont->frame.Ri = 0;
|
|
/* pointer initialisation */
|
pJpegDecCont->vlc.acTable0.vals = NULL;
|
pJpegDecCont->vlc.acTable1.vals = NULL;
|
pJpegDecCont->vlc.acTable2.vals = NULL;
|
pJpegDecCont->vlc.acTable3.vals = NULL;
|
|
pJpegDecCont->vlc.dcTable0.vals = NULL;
|
pJpegDecCont->vlc.dcTable1.vals = NULL;
|
pJpegDecCont->vlc.dcTable2.vals = NULL;
|
pJpegDecCont->vlc.dcTable3.vals = NULL;
|
|
pJpegDecCont->frame.pBuffer = NULL;
|
|
return;
|
}
|
|
/*------------------------------------------------------------------------------
|
|
Function name: JpegDecInitHW
|
|
Functional description:
|
Set up HW regs for decode
|
|
Inputs:
|
JpegDecContainer *pJpegDecCont
|
|
Outputs:
|
Returns OK when successful, NOK in case unknown message type is
|
asked
|
|
------------------------------------------------------------------------------*/
|
JpegDecRet JpegDecInitHW(JpegDecContainer * pJpegDecCont)
|
{
|
RK_U32 i;
|
RK_U32 coeffBuffer = 0;
|
JpegDecContainer *PTR_JPGC = pJpegDecCont;
|
|
ASSERT(pJpegDecCont);
|
|
TRACE_COMPONENT_ID(PTR_JPGC->info.componentId);
|
|
/* Check if first InitHw call */
|
if (PTR_JPGC->info.sliceStartCount == 0) {
|
/* Check if HW resource is available */
|
;
|
}
|
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DEC_TIMEOUT_E, 1);
|
|
/* frame size, round up the number of mbs */
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_PIC_MB_W_EXT,
|
((((PTR_JPGC->info.X) >> (4)) & 0xE00) >> 9));
|
|
/* frame size, round up the number of mbs */
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_PIC_MB_WIDTH,
|
((PTR_JPGC->info.X) >> (4)) & 0x1FF);
|
|
/* frame size, round up the number of mbs */
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_PIC_MB_H_EXT,
|
((((PTR_JPGC->info.Y) >> (4)) & 0x700) >> 8));
|
|
/* frame size, round up the number of mbs */
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_PIC_MB_HEIGHT_P,
|
((PTR_JPGC->info.Y) >> (4)) & 0x0FF);
|
|
JPEGDEC_TRACE_INTERNAL(("INTERNAL: Set decoding mode: JPEG\n"));
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DEC_MODE, JPEG_RK70_MODE_JPEG);
|
|
JPEGDEC_TRACE_INTERNAL(("INTERNAL: Set output write enabled\n"));
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DEC_OUT_DIS, 0); //wjm test
|
|
JPEGDEC_TRACE_INTERNAL(("INTERNAL: Set filtering disabled\n"));
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_FILTERING_DIS, 1);
|
|
JPEGDEC_TRACE_INTERNAL(("INTERNAL: Set amount of QP Table\n"));
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_JPEG_QTABLES,
|
PTR_JPGC->info.amountOfQTables);
|
|
JPEGDEC_TRACE_INTERNAL(("INTERNAL: Set input format\n"));
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_JPEG_MODE,
|
PTR_JPGC->info.yCbCrMode);
|
|
/* In case of JPEG: Always VLC mode used (0) */
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_RLC_MODE_E, PTR_JPGC->info.rlcMode);
|
|
JPEGDEC_TRACE_INTERNAL(("INTERNAL: Width is not multiple of 16\n"));
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_JPEG_FILRIGHT_E, PTR_JPGC->info.fillRight);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_PJPEG_FILDOWN_E,
|
PTR_JPGC->info.fillBottom);
|
|
JPEGDEC_TRACE_INTERNAL(("INTERNAL: Set slice %d\n", PTR_JPGC->info.sliceHeight));
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_JPEG_SLICE_H, //1); //wjm test
|
PTR_JPGC->info.sliceHeight);
|
|
/* Set JPEG operation mode */
|
if (PTR_JPGC->info.operationType != JPEGDEC_PROGRESSIVE) {
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_PJPEG_E, 0);
|
} else {
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_PJPEG_E, 1);
|
}
|
|
/* Set spectral selection start coefficient */
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_PJPEG_SS, PTR_JPGC->scan.Ss);
|
|
/* Set spectral selection end coefficient */
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_PJPEG_SE, PTR_JPGC->scan.Se);
|
|
/* Set the point transform used in the preceding scan */
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_PJPEG_AH, PTR_JPGC->scan.Ah);
|
|
/* Set the point transform value */
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_PJPEG_AL, PTR_JPGC->scan.Al);
|
|
/* Set needed progressive parameters */
|
if (PTR_JPGC->info.operationType == JPEGDEC_PROGRESSIVE) {
|
/* write coeff table base */
|
coeffBuffer = PTR_JPGC->info.pCoeffBase.phy_addr;
|
/* non-interleaved */
|
if (PTR_JPGC->info.nonInterleaved) {
|
for (i = 0; i < PTR_JPGC->info.componentId; i++) {
|
coeffBuffer += (JPEGDEC_COEFF_SIZE *
|
PTR_JPGC->frame.numBlocks[i]);
|
}
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_PJPEG_COEFF_BUF,
|
coeffBuffer);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DEC_OUT_DIS, 0);
|
}
|
/* interleaved components */
|
else {
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_PJPEG_COEFF_BUF,
|
coeffBuffer);
|
coeffBuffer += (JPEGDEC_COEFF_SIZE) * PTR_JPGC->frame.numBlocks[0];
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_PJPEG_DCCB_BASE,
|
coeffBuffer);
|
coeffBuffer += (JPEGDEC_COEFF_SIZE) * PTR_JPGC->frame.numBlocks[1];
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_PJPEG_DCCR_BASE,
|
coeffBuffer);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DEC_OUT_DIS, 1);
|
}
|
}
|
|
if (PTR_JPGC->info.operationType == JPEGDEC_BASELINE) {
|
/* write "length amounts" */
|
JpegDecWriteLenBits(PTR_JPGC);
|
/* Create AC/DC/QP tables for HW */
|
JpegDecWriteTables(PTR_JPGC);
|
//VPUMemClean(&(PTR_JPGC->frame.pTableBase));
|
//memset(PTR_JPGC->frame.pTableBase.vir_addr, 0, PTR_JPGC->frame.pTableBase.size);
|
} else if (PTR_JPGC->info.operationType == JPEGDEC_NONINTERLEAVED) {
|
/* write "length amounts" */
|
JpegDecWriteLenBitsNonInterleaved(PTR_JPGC);
|
|
/* Create AC/DC/QP tables for HW */
|
JpegDecWriteTablesNonInterleaved(PTR_JPGC);
|
} else {
|
/* write "length amounts" */
|
JpegDecWriteLenBitsProgressive(PTR_JPGC);
|
|
/* Create AC/DC/QP tables for HW */
|
JpegDecWriteTablesProgressive(PTR_JPGC);
|
}
|
/* Select which tables the chromas use */
|
JpegDecChromaTableSelectors(PTR_JPGC);
|
/* write table base */
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_QTABLE_BASE,
|
PTR_JPGC->frame.pTableBase.phy_addr);
|
|
/* set up stream position for HW decode */
|
JpegDecSetHwStrmParams(PTR_JPGC);
|
|
/* set restart interval */
|
if (PTR_JPGC->frame.Ri) {
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_SYNC_MARKER_E, 1);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_PJPEG_REST_FREQ,
|
PTR_JPGC->frame.Ri);
|
} else
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_SYNC_MARKER_E, 0);
|
|
/* Handle PP and output base addresses */
|
if (PTR_JPGC->ppInstance != NULL && PTR_JPGC->ppControl.usePipeline) {
|
JPEGDEC_TRACE_INTERNAL(("INTERNAL: Set output write disabled\n"));
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DEC_OUT_DIS, 1);
|
|
/* set output to zero, because of pp */
|
/* Luminance output */
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DEC_OUT_BASE, 0);
|
|
/* Chrominance output */
|
if (PTR_JPGC->image.sizeChroma) {
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_JPG_CH_OUT_BASE, 0);
|
}
|
|
PTR_JPGC->info.pipeline = 1;
|
} else {
|
/* Luminance output */
|
if (PTR_JPGC->info.operationType == JPEGDEC_BASELINE) {
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DEC_OUT_BASE,
|
PTR_JPGC->asicBuff.outLumaBuffer.phy_addr);
|
|
/* Chrominance output */
|
if (PTR_JPGC->image.sizeChroma) {
|
/* write output base */
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_JPG_CH_OUT_BASE,
|
(PTR_JPGC->asicBuff.outChromaBuffer.phy_addr & 0x3FF));
|
}
|
} else {
|
if (PTR_JPGC->info.componentId == 0) {
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DEC_OUT_BASE,
|
PTR_JPGC->asicBuff.outLumaBuffer.phy_addr);
|
} else if (PTR_JPGC->info.componentId == 1) {
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DEC_OUT_BASE,
|
PTR_JPGC->asicBuff.outChromaBuffer.phy_addr);
|
} else {
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DEC_OUT_BASE,
|
(PTR_JPGC->asicBuff.outChromaBuffer2.phy_addr));
|
}
|
}
|
|
PTR_JPGC->info.pipeline = 0;
|
}
|
|
PTR_JPGC->info.sliceStartCount = 1;
|
PTR_JPGC->asicRunning = 1;
|
|
/* Enable jpeg mode and set slice mode */
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DEC_E, 1);
|
|
/* Flush regs to hw register */
|
JpegFlushRegs(PTR_JPGC);
|
|
return JPEGDEC_OK;
|
}
|
|
/*------------------------------------------------------------------------------
|
|
Function name: JpegDecInitHWContinue
|
|
Functional description:
|
Set up HW regs for decode
|
|
Inputs:
|
JpegDecContainer *pJpegDecCont
|
|
Outputs:
|
Returns OK when successful, NOK in case unknown message type is
|
asked
|
|
------------------------------------------------------------------------------*/
|
void JpegDecInitHWContinue(JpegDecContainer * pJpegDecCont)
|
{
|
JpegDecContainer* PTR_JPGC = pJpegDecCont;
|
|
ASSERT(pJpegDecCont);
|
|
/* update slice counter */
|
PTR_JPGC->info.amountOfSlices++;
|
|
if (PTR_JPGC->ppInstance == NULL &&
|
PTR_JPGC->info.userAllocMem == 1 && PTR_JPGC->info.sliceStartCount > 0) {
|
/* if user allocated memory ==> new addresses */
|
PTR_JPGC->asicBuff.outLumaBuffer.vir_addr =
|
PTR_JPGC->info.givenOutLuma.vir_addr;
|
PTR_JPGC->asicBuff.outLumaBuffer.phy_addr =
|
PTR_JPGC->info.givenOutLuma.phy_addr;
|
PTR_JPGC->asicBuff.outChromaBuffer.vir_addr =
|
PTR_JPGC->info.givenOutChroma.vir_addr;
|
PTR_JPGC->asicBuff.outChromaBuffer.phy_addr =
|
PTR_JPGC->info.givenOutChroma.phy_addr;
|
}
|
|
/* Update only register/values that might have been changed */
|
|
/*************** Set swreg1 data ************/
|
/* clear status bit */
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DEC_SLICE_INT, 0);
|
|
/*************** Set swreg5 data ************/
|
JPEGDEC_TRACE_INTERNAL(("INTERNAL CONTINUE: Set stream last buffer bit\n"));
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_JPEG_STREAM_ALL,
|
PTR_JPGC->info.streamEnd);
|
|
/*************** Set swreg13 data ************/
|
/* PP depending register writes */
|
if (PTR_JPGC->ppInstance == NULL) {
|
/* Luminance output */
|
JPEGDEC_TRACE_INTERNAL(("INTERNAL CONTINUE: Set LUMA OUTPUT data base address\n"));
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DEC_OUT_BASE,
|
PTR_JPGC->asicBuff.outLumaBuffer.phy_addr);
|
|
/*************** Set swreg14 data ************/
|
|
/* Chrominance output */
|
if (PTR_JPGC->image.sizeChroma) {
|
/* write output base */
|
JPEGDEC_TRACE_INTERNAL(("INTERNAL CONTINUE: Set CHROMA OUTPUT data base address\n"));
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_JPG_CH_OUT_BASE,
|
PTR_JPGC->asicBuff.outChromaBuffer.phy_addr);
|
}
|
|
PTR_JPGC->info.pipeline = 0;
|
}
|
|
/*************** Set swreg13 data ************/
|
/* PP depending register writes */
|
if (PTR_JPGC->ppInstance != NULL && PTR_JPGC->ppControl.usePipeline == 0) {
|
if (PTR_JPGC->info.yCbCrMode == JPEGDEC_YUV420) {
|
PTR_JPGC->info.lumaPos = (PTR_JPGC->info.X *
|
(PTR_JPGC->info.sliceMbSetValue * 16));
|
PTR_JPGC->info.chromaPos = ((PTR_JPGC->info.X) *
|
(PTR_JPGC->info.sliceMbSetValue * 8));
|
} else if (PTR_JPGC->info.yCbCrMode == JPEGDEC_YUV422) {
|
PTR_JPGC->info.lumaPos = (PTR_JPGC->info.X *
|
(PTR_JPGC->info.sliceMbSetValue * 16));
|
PTR_JPGC->info.chromaPos = ((PTR_JPGC->info.X) *
|
(PTR_JPGC->info.sliceMbSetValue * 16));
|
} else if (PTR_JPGC->info.yCbCrMode == JPEGDEC_YUV440) {
|
PTR_JPGC->info.lumaPos = (PTR_JPGC->info.X *
|
(PTR_JPGC->info.sliceMbSetValue * 16));
|
PTR_JPGC->info.chromaPos = ((PTR_JPGC->info.X) *
|
(PTR_JPGC->info.sliceMbSetValue * 16));
|
} else {
|
PTR_JPGC->info.lumaPos = (PTR_JPGC->info.X *
|
(PTR_JPGC->info.sliceMbSetValue * 16));
|
PTR_JPGC->info.chromaPos = 0;
|
}
|
|
/* update luma/chroma position */
|
PTR_JPGC->info.lumaPos = (PTR_JPGC->info.lumaPos *
|
PTR_JPGC->info.amountOfSlices);
|
if (PTR_JPGC->info.chromaPos) {
|
PTR_JPGC->info.chromaPos = (PTR_JPGC->info.chromaPos *
|
PTR_JPGC->info.amountOfSlices);
|
}
|
|
/* Luminance output */
|
JPEGDEC_TRACE_INTERNAL(("INTERNAL CONTINUE: Set LUMA OUTPUT data base address\n"));
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DEC_OUT_BASE,
|
PTR_JPGC->asicBuff.outLumaBuffer.phy_addr +
|
PTR_JPGC->info.lumaPos);
|
|
/*************** Set swreg14 data ************/
|
|
/* Chrominance output */
|
if (PTR_JPGC->image.sizeChroma) {
|
/* write output base */
|
JPEGDEC_TRACE_INTERNAL(("INTERNAL CONTINUE: Set CHROMA OUTPUT data base address\n"));
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_JPG_CH_OUT_BASE,
|
PTR_JPGC->asicBuff.outChromaBuffer.phy_addr +
|
PTR_JPGC->info.chromaPos);
|
}
|
|
PTR_JPGC->info.pipeline = 0;
|
}
|
|
/*************** Set swreg15 data ************/
|
JPEGDEC_TRACE_INTERNAL(("INTERNAL CONTINUE: Set slice/full mode: 0 full; other = slice\n"));
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_JPEG_SLICE_H,
|
PTR_JPGC->info.sliceHeight);
|
|
/* Flush regs to hw register */
|
JpegFlushRegs(pJpegDecCont);
|
}
|
|
/*------------------------------------------------------------------------------
|
|
Function name: JpegDecInitHWInputBuffLoad
|
|
Functional description:
|
Set up HW regs for decode after input buffer load
|
|
Inputs:
|
JpegDecContainer *pJpegDecCont
|
|
Outputs:
|
Returns OK when successful, NOK in case unknown message type is
|
asked
|
|
------------------------------------------------------------------------------*/
|
void JpegDecInitHWInputBuffLoad(JpegDecContainer * pJpegDecCont)
|
{
|
JpegDecContainer *PTR_JPGC = pJpegDecCont;
|
|
ASSERT(pJpegDecCont);
|
|
/* Update only register/values that might have been changed */
|
/*************** Set swreg4 data ************/
|
/* frame size, round up the number of mbs */
|
JPEGDEC_TRACE_INTERNAL(("INTERNAL: Set Frame width extension\n"));
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_PIC_MB_W_EXT,
|
((((PTR_JPGC->info.X) >> (4)) & 0xE00) >> 9));
|
|
/* frame size, round up the number of mbs */
|
JPEGDEC_TRACE_INTERNAL(("INTERNAL: Set Frame width\n"));
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_PIC_MB_WIDTH,
|
((PTR_JPGC->info.X) >> (4)) & 0x1FF);
|
|
/* frame size, round up the number of mbs */
|
JPEGDEC_TRACE_INTERNAL(("INTERNAL: Set Frame height extension\n"));
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_PIC_MB_H_EXT,
|
((((PTR_JPGC->info.Y) >> (4)) & 0x700) >> 8));
|
|
/* frame size, round up the number of mbs */
|
JPEGDEC_TRACE_INTERNAL(("INTERNAL: Set Frame height\n"));
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_PIC_MB_HEIGHT_P,
|
((PTR_JPGC->info.Y) >> (4)) & 0x0FF);
|
|
/*************** Set swreg5 data ************/
|
JPEGDEC_TRACE_INTERNAL(("INTERNAL BUFFER LOAD: Set stream start bit\n"));
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_STRM_START_BIT,
|
PTR_JPGC->stream.bitPosInByte);
|
|
/*************** Set swreg6 data ************/
|
JPEGDEC_TRACE_INTERNAL(("INTERNAL BUFFER LOAD: Set stream length\n"));
|
|
/* check if all stream will processed in this buffer */
|
if ((PTR_JPGC->info.decodedStreamLen) >= PTR_JPGC->stream.streamLength) {
|
PTR_JPGC->info.streamEnd = 1;
|
}
|
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_STREAM_LEN,
|
PTR_JPGC->info.inputBufferLen);
|
|
/*************** Set swreg4 data ************/
|
JPEGDEC_TRACE_INTERNAL(("INTERNAL BUFFER LOAD: Set stream last buffer bit\n"));
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_JPEG_STREAM_ALL,
|
PTR_JPGC->info.streamEnd);
|
|
/*************** Set swreg12 data ************/
|
JPEGDEC_TRACE_INTERNAL(("INTERNAL BUFFER LOAD: Set stream start address\n"));
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_RLC_VLC_BASE,
|
PTR_JPGC->stream.streamBus);
|
|
JPEGDEC_TRACE_INTERNAL(("INTERNAL BUFFER LOAD: Stream bus start 0x%08x\n",
|
PTR_JPGC->stream.streamBus));
|
JPEGDEC_TRACE_INTERNAL(("INTERNAL BUFFER LOAD: Bit position 0x%08x\n",
|
PTR_JPGC->stream.bitPosInByte));
|
JPEGDEC_TRACE_INTERNAL(("INTERNAL BUFFER LOAD: Stream length 0x%08x\n",
|
PTR_JPGC->stream.streamLength));
|
|
/* Flush regs to hw register */
|
JpegFlushRegs(pJpegDecCont);
|
}
|
|
/*------------------------------------------------------------------------------
|
|
Function name: JpegDecInitHWProgressiveContinue
|
|
Functional description:
|
Set up HW regs for decode after progressive scan decoded
|
|
Inputs:
|
JpegDecContainer *pJpegDecCont
|
|
Outputs:
|
Returns OK when successful, NOK in case unknown message type is
|
asked
|
|
------------------------------------------------------------------------------*/
|
void JpegDecInitHWProgressiveContinue(JpegDecContainer * pJpegDecCont)
|
{
|
JpegDecContainer *PTR_JPGC = pJpegDecCont;
|
|
RK_U32 i;
|
RK_U32 coeffBuffer = 0;
|
RK_U32 outputBuffer = 0;
|
|
ASSERT(pJpegDecCont);
|
|
if (PTR_JPGC->ppInstance == NULL && PTR_JPGC->info.userAllocMem == 1) {
|
/* if user allocated memory ==> new addresses */
|
PTR_JPGC->asicBuff.outLumaBuffer.vir_addr =
|
PTR_JPGC->info.givenOutLuma.vir_addr;
|
PTR_JPGC->asicBuff.outLumaBuffer.phy_addr =
|
PTR_JPGC->info.givenOutLuma.phy_addr;
|
PTR_JPGC->asicBuff.outChromaBuffer.vir_addr =
|
PTR_JPGC->info.givenOutChroma.vir_addr;
|
PTR_JPGC->asicBuff.outChromaBuffer.phy_addr =
|
PTR_JPGC->info.givenOutChroma.phy_addr;
|
PTR_JPGC->asicBuff.outChromaBuffer2.vir_addr =
|
PTR_JPGC->info.givenOutChroma2.vir_addr;
|
PTR_JPGC->asicBuff.outChromaBuffer2.phy_addr =
|
PTR_JPGC->info.givenOutChroma2.phy_addr;
|
}
|
|
TRACE_COMPONENT_ID(PTR_JPGC->info.componentId);
|
/* Update only register/values that might have been changed */
|
|
/*************** Set swreg13 data ************/
|
/* Luminance output */
|
if (PTR_JPGC->info.componentId == 0)
|
outputBuffer = PTR_JPGC->asicBuff.outLumaBuffer.phy_addr;
|
else if (PTR_JPGC->info.componentId == 1)
|
outputBuffer = (PTR_JPGC->asicBuff.outChromaBuffer.phy_addr);
|
else
|
outputBuffer = (PTR_JPGC->asicBuff.outChromaBuffer2.phy_addr);
|
|
JPEGDEC_TRACE_INTERNAL(("INTERNAL: Set LUMA OUTPUT data base address\n"));
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DEC_OUT_BASE, outputBuffer);
|
|
PTR_JPGC->info.pipeline = 0;
|
|
/* set up stream position for HW decode */
|
JPEGDEC_TRACE_INTERNAL(("INTERNAL: Set stream position for HW\n"));
|
JpegDecSetHwStrmParams(PTR_JPGC);
|
|
/*************** Set swreg5 data ************/
|
JPEGDEC_TRACE_INTERNAL(("INTERNAL: Set input format\n"));
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_JPEG_MODE,
|
PTR_JPGC->info.yCbCrMode);
|
|
/* frame size, round up the number of mbs */
|
JPEGDEC_TRACE_INTERNAL(("INTERNAL: Set Frame width extension\n"));
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_PIC_MB_W_EXT,
|
((((PTR_JPGC->info.X) >> (4)) & 0xE00) >> 9));
|
|
/* frame size, round up the number of mbs */
|
JPEGDEC_TRACE_INTERNAL(("INTERNAL: Set Frame width\n"));
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_PIC_MB_WIDTH,
|
((PTR_JPGC->info.X) >> (4)) & 0x1FF);
|
|
/* frame size, round up the number of mbs */
|
JPEGDEC_TRACE_INTERNAL(("INTERNAL: Set Frame height extension\n"));
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_PIC_MB_H_EXT,
|
((((PTR_JPGC->info.Y) >> (4)) & 0x700) >> 8));
|
|
/* frame size, round up the number of mbs */
|
JPEGDEC_TRACE_INTERNAL(("INTERNAL: Set Frame height\n"));
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_PIC_MB_HEIGHT_P,
|
((PTR_JPGC->info.Y) >> (4)) & 0x0FF);
|
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_PJPEG_WDIV8, PTR_JPGC->info.fillX);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_JPEG_FILRIGHT_E,
|
PTR_JPGC->info.fillX || PTR_JPGC->info.fillRight);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_PJPEG_HDIV8, PTR_JPGC->info.fillY);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_PJPEG_FILDOWN_E,
|
PTR_JPGC->info.fillY || PTR_JPGC->info.fillBottom);
|
|
/*************** Set swreg52 data ************/
|
/* Set JPEG operation mode */
|
JPEGDEC_TRACE_INTERNAL(("INTERNAL: Set JPEG operation mode\n"));
|
if (PTR_JPGC->info.operationType != JPEGDEC_PROGRESSIVE) {
|
/* Set JPEG operation mode */
|
JPEGDEC_TRACE_INTERNAL(("INTERNAL: Set JPEG operation mode\n"));
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_PJPEG_E, 0);
|
} else {
|
/* Set JPEG operation mode */
|
JPEGDEC_TRACE_INTERNAL(("INTERNAL: Set JPEG operation mode\n"));
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_PJPEG_E, 1);
|
}
|
|
/* Set spectral selection start coefficient */
|
JPEGDEC_TRACE_INTERNAL(("INTERNAL: Set JPEG operation mode\n"));
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_PJPEG_SS, PTR_JPGC->scan.Ss);
|
|
/* Set spectral selection end coefficient */
|
JPEGDEC_TRACE_INTERNAL(("INTERNAL: Set JPEG operation mode\n"));
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_PJPEG_SE, PTR_JPGC->scan.Se);
|
|
/* Set the point transform used in the preceding scan */
|
JPEGDEC_TRACE_INTERNAL(("INTERNAL: Set JPEG operation mode\n"));
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_PJPEG_AH, PTR_JPGC->scan.Ah);
|
|
/* Set the point transform value */
|
JPEGDEC_TRACE_INTERNAL(("INTERNAL: Set JPEG operation mode\n"));
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_PJPEG_AL, PTR_JPGC->scan.Al);
|
|
/* Set needed progressive parameters */
|
if (PTR_JPGC->info.operationType == JPEGDEC_PROGRESSIVE) {
|
JPEGDEC_TRACE_INTERNAL(("INTERNAL: Set coefficient buffer base address\n"));
|
coeffBuffer = PTR_JPGC->info.pCoeffBase.phy_addr;
|
/* non-interleaved */
|
if (PTR_JPGC->info.nonInterleaved) {
|
for (i = 0; i < PTR_JPGC->info.componentId; i++) {
|
coeffBuffer += (JPEGDEC_COEFF_SIZE *
|
PTR_JPGC->frame.numBlocks[i]);
|
}
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_PJPEG_COEFF_BUF,
|
coeffBuffer);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DEC_OUT_DIS, 0);
|
}
|
/* interleaved components */
|
else {
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_PJPEG_COEFF_BUF,
|
coeffBuffer);
|
coeffBuffer += (JPEGDEC_COEFF_SIZE) * PTR_JPGC->frame.numBlocks[0];
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_PJPEG_DCCB_BASE,
|
coeffBuffer);
|
coeffBuffer += (JPEGDEC_COEFF_SIZE) * PTR_JPGC->frame.numBlocks[1];
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_PJPEG_DCCR_BASE,
|
coeffBuffer);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DEC_OUT_DIS, 1);
|
}
|
}
|
|
/* write "length amounts" */
|
JPEGDEC_TRACE_INTERNAL(("INTERNAL: Write VLC length amounts to register\n"));
|
JpegDecWriteLenBitsProgressive(PTR_JPGC);
|
|
/* Create AC/DC/QP tables for HW */
|
JPEGDEC_TRACE_INTERNAL(("INTERNAL: Write AC,DC,QP tables to base\n"));
|
JpegDecWriteTablesProgressive(PTR_JPGC);
|
|
/* Select which tables the chromas use */
|
JPEGDEC_TRACE_INTERNAL(("INTERNAL: Select chroma AC,DC tables\n"));
|
JpegDecChromaTableSelectors(PTR_JPGC);
|
|
/* write table base */
|
JPEGDEC_TRACE_INTERNAL(("INTERNAL: Set AC,DC,QP table base address\n"));
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_QTABLE_BASE,
|
PTR_JPGC->frame.pTableBase.phy_addr);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_JPEG_QTABLES,
|
PTR_JPGC->info.amountOfQTables);
|
|
if (PTR_JPGC->info.sliceMbSetValue) {
|
/*************** Set swreg15 data ************/
|
JPEGDEC_TRACE_INTERNAL(("INTERNAL CONTINUE: Set slice/full mode: 0 full; other = slice\n"));
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_JPEG_SLICE_H,
|
PTR_JPGC->info.sliceHeight);
|
}
|
|
/* set restart interval */
|
if (PTR_JPGC->frame.Ri) {
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_SYNC_MARKER_E, 1);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_REFER13_BASE,
|
PTR_JPGC->frame.Ri);
|
} else
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_SYNC_MARKER_E, 0);
|
|
PTR_JPGC->asicRunning = 1;
|
|
|
/* Enable jpeg mode and set slice mode */
|
JPEGDEC_TRACE_INTERNAL(("INTERNAL: Enable jpeg\n"));
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DEC_E, 1);
|
/* Flush regs to hw register */
|
JpegFlushRegs(PTR_JPGC);
|
}
|
|
/*------------------------------------------------------------------------------
|
|
Function name: JpegDecSetHwStrmParams
|
|
Functional description:
|
set up hw stream start position
|
|
Inputs:
|
JpegDecContainer *pJpegDecCont
|
|
Outputs:
|
void
|
|
------------------------------------------------------------------------------*/
|
static void JpegDecSetHwStrmParams(JpegDecContainer * pJpegDecCont)
|
{
|
JpegDecContainer *PTR_JPGC = pJpegDecCont;
|
StreamStorage *JPG_STR = &pJpegDecCont->stream;
|
|
RK_U32 addrTmp = 0;
|
RK_U32 amountOfStream = 0;
|
|
/* calculate and set stream start address to hw */
|
JPEGDEC_TRACE_INTERNAL(("INTERNAL: read bits %d\n", JPG_STR->readBits));
|
JPEGDEC_TRACE_INTERNAL(("INTERNAL: read bytes %d\n", JPG_STR->readBits / 8));
|
JPEGDEC_TRACE_INTERNAL(("INTERNAL: Stream bus start 0x%08x\n",
|
JPG_STR->streamBus));
|
JPEGDEC_TRACE_INTERNAL(("INTERNAL: Stream virtual start 0x%08x\n",
|
JPG_STR->pStartOfStream));
|
|
/* calculate and set stream start address to hw */
|
addrTmp = (((RK_U32) JPG_STR->pStartOfStream & 0x3) +
|
(RK_U32) (JPG_STR->pCurrPos - JPG_STR->pStartOfStream)) & (~7);
|
|
JPEGDEC_TRACE_INTERNAL(("pStartOfStream data : 0x%x, 0x%x, 0x%x, 0x%x", JPG_STR->pStartOfStream[JPG_STR->streamLength - 4],
|
JPG_STR->pStartOfStream[JPG_STR->streamLength - 3], JPG_STR->pStartOfStream[JPG_STR->streamLength - 2], JPG_STR->pStartOfStream[JPG_STR->streamLength - 1]));
|
|
/* if (!VPUMemJudgeIommu()) {
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_RLC_VLC_BASE, (RK_U32)JPG_STR->streamBus + addrTmp);
|
} else {*/
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_RLC_VLC_BASE, (RK_U32)JPG_STR->streamBus | (addrTmp << 10));
|
//}
|
|
JPEGDEC_TRACE_INTERNAL(("INTERNAL: Stream bus start 0x%08x\n",
|
JPG_STR->streamBus));
|
JPEGDEC_TRACE_INTERNAL(("INTERNAL: Start Addr 0x%08x\n",
|
(PTR_JPGC->reghandle)));
|
|
/* calculate and set stream start bit to hw */
|
|
/* change current pos to bus address style */
|
/* remove three lowest bits and add the difference to bitPosInWord */
|
/* used as bit pos in word not as bit pos in byte actually... */
|
switch ((RK_U32) JPG_STR->pCurrPos & (7)) {
|
case 0:
|
break;
|
case 1:
|
JPG_STR->bitPosInByte += 8;
|
break;
|
case 2:
|
JPG_STR->bitPosInByte += 16;
|
break;
|
case 3:
|
JPG_STR->bitPosInByte += 24;
|
break;
|
case 4:
|
JPG_STR->bitPosInByte += 32;
|
break;
|
case 5:
|
JPG_STR->bitPosInByte += 40;
|
break;
|
case 6:
|
JPG_STR->bitPosInByte += 48;
|
break;
|
case 7:
|
JPG_STR->bitPosInByte += 56;
|
break;
|
default:
|
ASSERT(0);
|
break;
|
}
|
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_STRM_START_BIT,
|
JPG_STR->bitPosInByte);
|
|
/* set up stream length for HW.
|
* length = size of original buffer - stream we already decoded in SW */
|
JPG_STR->pCurrPos = (RK_U8 *) ((RK_U32) JPG_STR->pCurrPos & (~7));
|
|
if (PTR_JPGC->info.inputStreaming) {
|
amountOfStream = (PTR_JPGC->info.inputBufferLen -
|
(RK_U32) (JPG_STR->pCurrPos - JPG_STR->pStartOfStream));
|
|
/* NOTE: on2 hardware bug, need increase length of input stream
|
* when height is not aligned as 16 Bytes.
|
*/
|
if ((PTR_JPGC->frame.Y % 16) &&
|
(PTR_JPGC->info.yCbCrMode == JPEGDEC_YUV422 ||
|
PTR_JPGC->info.yCbCrMode == JPEGDEC_YUV444 ||
|
PTR_JPGC->info.yCbCrMode == JPEGDEC_YUV411)) {
|
amountOfStream += 100; /* 100 can work so far, but may be inappropriate in some cases */
|
}
|
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_STREAM_LEN, amountOfStream);
|
PTR_JPGC->info.streamEnd = 1;
|
} else {
|
amountOfStream = (JPG_STR->streamLength -
|
(RK_U32) (JPG_STR->pCurrPos - JPG_STR->pStartOfStream));
|
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_STREAM_LEN, amountOfStream);
|
|
/* because no input streaming, frame should be ready during decoding this buffer */
|
PTR_JPGC->info.streamEnd = 1;
|
}
|
|
JPEGDEC_TRACE_INTERNAL(("INTERNAL: Set stream last buffer bit\n"));
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_JPEG_STREAM_ALL, //0);
|
PTR_JPGC->info.streamEnd);
|
|
JPEGDEC_TRACE_INTERNAL(("INTERNAL: JPG_STR->streamLength %d\n",
|
JPG_STR->streamLength));
|
JPEGDEC_TRACE_INTERNAL(("INTERNAL: JPG_STR->pCurrPos 0x%08x\n",
|
(RK_U32) JPG_STR->pCurrPos));
|
JPEGDEC_TRACE_INTERNAL(("INTERNAL: JPG_STR->pStartOfStream 0x%08x\n",
|
(RK_U32) JPG_STR->pStartOfStream));
|
JPEGDEC_TRACE_INTERNAL(("INTERNAL: JPG_STR->bitPosInByte 0x%08x\n",
|
JPG_STR->bitPosInByte));
|
|
return;
|
}
|
|
/*------------------------------------------------------------------------------
|
|
Function name: JpegDecAllocateResidual
|
|
Functional description:
|
Allocates residual buffer
|
|
Inputs:
|
JpegDecContainer *pJpegDecCont Pointer to DecData structure
|
|
Outputs:
|
OK
|
JPEGDEC_MEMFAIL
|
|
------------------------------------------------------------------------------*/
|
JpegDecRet JpegDecAllocateResidual(JpegDecContainer * pJpegDecCont)
|
{
|
JpegDecContainer *PTR_JPGC = pJpegDecCont;
|
RK_S32 tmp = JPEGDEC_ERROR;
|
RK_U32 numBlocks = 0;
|
RK_U32 i;
|
RK_U32 tableSize = 0;
|
|
ASSERT(PTR_JPGC);
|
|
/*if(PTR_JPGC->info.operationType == JPEGDEC_PROGRESSIVE)
|
{
|
for(i = 0; i < PTR_JPGC->frame.Nf; i++)
|
{
|
numBlocks += PTR_JPGC->frame.numBlocks[i];
|
}
|
|
// allocate coefficient buffer
|
tmp = VPUMallocLinear(&(PTR_JPGC->info.pCoeffBase), (sizeof(RK_U8) * (JPEGDEC_COEFF_SIZE *
|
numBlocks)));
|
if(tmp == -1)
|
{
|
return (JPEGDEC_MEMFAIL);
|
}
|
#ifdef PJPEG_COMPONENT_TRACE
|
pjpegCoeffBase = PTR_JPGC->info.pCoeffBase.vir_addr;
|
pjpegCoeffSize = numBlocks * JPEGDEC_COEFF_SIZE;
|
#endif
|
|
JPEGDEC_TRACE_INTERNAL(("ALLOCATE: COEFF virtual %x bus %x\n",
|
(RK_U32) PTR_JPGC->info.pCoeffBase.vir_addr,
|
PTR_JPGC->info.pCoeffBase.phy_addr));
|
if(PTR_JPGC->frame.Nf > 1)
|
{
|
tmp = VPUMallocLinear(&PTR_JPGC->info.tmpStrm, sizeof(RK_U8) * 100);
|
if(tmp == -1)
|
{
|
return (JPEGDEC_MEMFAIL);
|
}
|
}
|
|
}*/
|
|
/* QP/VLC memory size */
|
if (PTR_JPGC->info.operationType == JPEGDEC_PROGRESSIVE)
|
tableSize = JPEGDEC_PROGRESSIVE_TABLE_SIZE;
|
else
|
tableSize = JPEGDEC_BASELINE_TABLE_SIZE;
|
if (PTR_JPGC->frame.pTableBase.vir_addr == NULL) {
|
/* allocate VLC/QP table */
|
#ifdef DRM_LINUX
|
if (allocator_drm.alloc) {
|
printf("pTableBase alloc ************\n");
|
PTR_JPGC->frame.pTableBase.size = sizeof(RK_U8) * tableSize;
|
tmp = allocator_drm.alloc(PTR_JPGC->ctx, &(PTR_JPGC->frame.pTableBase));
|
allocator_drm.mmap(PTR_JPGC->ctx, &(PTR_JPGC->frame.pTableBase));
|
|
printf("pTableBase sucess tmp=%d************\n", tmp);
|
}
|
#else
|
tmp = VPUMallocLinear(&(PTR_JPGC->frame.pTableBase), (sizeof(RK_U8) * tableSize));
|
#endif
|
if (tmp == -1) {
|
return (JPEGDEC_MEMFAIL);
|
}
|
} else {
|
if (tableSize != PTR_JPGC->frame.pTableBase.size) {
|
#ifdef DRM_LINUX
|
if (allocator_drm.free) {
|
//VPUFreeLinear(&PTR_JPGC->frame.pTableBase);
|
allocator_drm.free(PTR_JPGC->ctx, &PTR_JPGC->frame.pTableBase);
|
}
|
/* allocate VLC/QP table */
|
if (allocator_drm.alloc) {
|
printf("pTableBase alloc 2************\n");
|
PTR_JPGC->frame.pTableBase.size = sizeof(RK_U8) * tableSize;
|
tmp = allocator_drm.alloc(PTR_JPGC->ctx, &(PTR_JPGC->frame.pTableBase));
|
allocator_drm.mmap(PTR_JPGC->ctx, &(PTR_JPGC->frame.pTableBase));
|
//tmp = VPUMallocLinear(&(PTR_JPGC->frame.pTableBase), (sizeof(RK_U8) * tableSize));
|
}
|
#else
|
VPUFreeLinear(&PTR_JPGC->frame.pTableBase);
|
tmp = VPUMallocLinear(&(PTR_JPGC->frame.pTableBase), (sizeof(RK_U8) * tableSize));
|
#endif
|
if (tmp == -1) {
|
return (JPEGDEC_MEMFAIL);
|
}
|
}
|
}
|
|
printf("ALLOCATE: VLC/QP virtual %p fd= 0x%x\n",
|
PTR_JPGC->frame.pTableBase.vir_addr,
|
PTR_JPGC->frame.pTableBase.phy_addr);
|
|
/*if(PTR_JPGC->ppInstance != NULL)
|
{
|
// PTR_JPGC->PPConfigQuery(PTR_JPGC->ppInstance, &PTR_JPGC->ppConfigQuery);
|
|
PTR_JPGC->ppControl.usePipeline = 1;
|
|
if(!PTR_JPGC->ppControl.usePipeline)
|
{
|
PTR_JPGC->image.sizeLuma = (PTR_JPGC->info.X * PTR_JPGC->info.Y);
|
if(PTR_JPGC->image.sizeChroma)
|
{
|
if(PTR_JPGC->info.yCbCrMode == JPEGDEC_YUV420)
|
PTR_JPGC->image.sizeChroma = (PTR_JPGC->image.sizeLuma / 2);
|
else if(PTR_JPGC->info.yCbCrMode == JPEGDEC_YUV422 ||
|
PTR_JPGC->info.yCbCrMode == JPEGDEC_YUV440)
|
PTR_JPGC->image.sizeChroma = PTR_JPGC->image.sizeLuma;
|
}
|
}
|
}*/
|
|
/* if pipelined PP -> decoder's output is not written external memory */
|
if (PTR_JPGC->ppInstance == NULL ||
|
(PTR_JPGC->ppInstance != NULL && !PTR_JPGC->ppControl.usePipeline)) {
|
if (PTR_JPGC->info.givenOutLuma.vir_addr == NULL) {
|
int timeout = 0;
|
#if 0
|
if (PTR_JPGC->asicBuff.outLumaBuffer.phy_addr)
|
VPUFreeLinear(&PTR_JPGC->asicBuff.outLumaBuffer);
|
|
while (VPUMallocLinear(&PTR_JPGC->asicBuff.outLumaBuffer, (PTR_JPGC->image.sizeLuma + (PTR_JPGC->image.sizeChroma)))) {
|
usleep(5000);
|
timeout++;
|
if (timeout > 0xFF) {
|
ALOGE("MJPEG Malloc outbuf Failed \n");
|
return (JPEGDEC_MEMFAIL);
|
}
|
}
|
#endif
|
PTR_JPGC->asicBuff.outLumaBuffer = *PTR_JPGC->pictureMem;
|
|
/* luma bus address to output */
|
PTR_JPGC->info.outLuma = PTR_JPGC->asicBuff.outLumaBuffer;
|
|
if (PTR_JPGC->image.sizeChroma) {
|
PTR_JPGC->asicBuff.outChromaBuffer.phy_addr = PTR_JPGC->asicBuff.outLumaBuffer.phy_addr + (PTR_JPGC->image.sizeLuma << 10);
|
|
if (PTR_JPGC->info.operationType != JPEGDEC_BASELINE) {
|
PTR_JPGC->asicBuff.outChromaBuffer2.phy_addr = PTR_JPGC->asicBuff.outChromaBuffer.phy_addr + ((PTR_JPGC->image.sizeChroma / 2) << 10);
|
} else {
|
PTR_JPGC->asicBuff.outChromaBuffer2.phy_addr = 0;
|
}
|
|
// chroma bus address to output
|
PTR_JPGC->info.outChroma = PTR_JPGC->asicBuff.outChromaBuffer;
|
PTR_JPGC->info.outChroma2 = PTR_JPGC->asicBuff.outChromaBuffer2;
|
}
|
} else {
|
PTR_JPGC->asicBuff.outLumaBuffer.vir_addr =
|
PTR_JPGC->info.givenOutLuma.vir_addr;
|
PTR_JPGC->asicBuff.outLumaBuffer.phy_addr =
|
PTR_JPGC->info.givenOutLuma.phy_addr;
|
|
PTR_JPGC->asicBuff.outChromaBuffer.vir_addr =
|
PTR_JPGC->info.givenOutChroma.vir_addr;
|
PTR_JPGC->asicBuff.outChromaBuffer.phy_addr =
|
PTR_JPGC->info.givenOutChroma.phy_addr;
|
PTR_JPGC->asicBuff.outChromaBuffer2.vir_addr =
|
PTR_JPGC->info.givenOutChroma2.vir_addr;
|
PTR_JPGC->asicBuff.outChromaBuffer2.phy_addr =
|
PTR_JPGC->info.givenOutChroma2.phy_addr;
|
|
PTR_JPGC->asicBuff.outLumaBuffer = *PTR_JPGC->pictureMem;
|
/* luma bus address to output */
|
PTR_JPGC->info.outLuma = PTR_JPGC->asicBuff.outLumaBuffer;
|
|
if (PTR_JPGC->image.sizeChroma) {
|
// chroma bus address to output
|
PTR_JPGC->info.outChroma = PTR_JPGC->asicBuff.outChromaBuffer;
|
PTR_JPGC->info.outChroma2 = PTR_JPGC->asicBuff.outChromaBuffer2;
|
}
|
|
/* flag to release */
|
PTR_JPGC->info.userAllocMem = 1;
|
}
|
printf("ALLOCATE: Luma virtual %p bus 0x%x\n",
|
PTR_JPGC->asicBuff.outLumaBuffer.vir_addr,
|
PTR_JPGC->asicBuff.outLumaBuffer.phy_addr);
|
|
printf("ALLOCATE: Chroma virtual 0x%x bus %x\n",
|
(RK_U32) PTR_JPGC->asicBuff.outChromaBuffer.vir_addr,
|
PTR_JPGC->asicBuff.outChromaBuffer.phy_addr);
|
}
|
|
#ifdef JPEGDEC_RESET_OUTPUT
|
{
|
(void) DWLmemset(PTR_JPGC->asicBuff.outLumaBuffer.vir_addr,
|
128, PTR_JPGC->image.sizeLuma);
|
if (PTR_JPGC->image.sizeChroma) {
|
if (PTR_JPGC->info.operationType != JPEGDEC_BASELINE) {
|
(void) DWLmemset(PTR_JPGC->asicBuff.outChromaBuffer.
|
vir_addr, 128,
|
PTR_JPGC->image.sizeChroma / 2);
|
(void) DWLmemset(PTR_JPGC->asicBuff.outChromaBuffer2.
|
vir_addr, 128,
|
PTR_JPGC->image.sizeChroma / 2);
|
} else
|
(void) DWLmemset(PTR_JPGC->asicBuff.outChromaBuffer.
|
vir_addr, 128,
|
PTR_JPGC->image.sizeChroma);
|
}
|
(void) DWLmemset(PTR_JPGC->frame.pTableBase.vir_addr, 0,
|
(sizeof(RK_U8) * tableSize));
|
if (PTR_JPGC->info.operationType == JPEGDEC_PROGRESSIVE) {
|
(void) DWLmemset(PTR_JPGC->info.pCoeffBase.vir_addr, 0,
|
(sizeof(RK_U8) * JPEGDEC_COEFF_SIZE * numBlocks));
|
}
|
}
|
#endif /* #ifdef JPEGDEC_RESET_OUTPUT */
|
|
return JPEGDEC_OK;
|
}
|
|
/*------------------------------------------------------------------------------
|
|
Function name: JpegDecSliceSizeCalculation
|
|
Functional description:
|
Calculates slice size
|
|
Inputs:
|
JpegDecContainer *pJpegDecCont
|
|
Outputs:
|
void
|
|
------------------------------------------------------------------------------*/
|
void JpegDecSliceSizeCalculation(JpegDecContainer * pJpegDecCont)
|
{
|
JpegDecContainer *PTR_JPGC = pJpegDecCont;
|
|
if (((PTR_JPGC->info.SliceCount +
|
1) * (PTR_JPGC->info.sliceMbSetValue * 16)) > PTR_JPGC->info.Y) {
|
PTR_JPGC->info.sliceHeight = ((PTR_JPGC->info.Y / 16) -
|
(PTR_JPGC->info.SliceCount *
|
PTR_JPGC->info.sliceHeight));
|
} else {
|
/* TODO! other sampling formats also than YUV420 */
|
if (PTR_JPGC->info.operationType == JPEGDEC_PROGRESSIVE &&
|
PTR_JPGC->info.componentId != 0)
|
PTR_JPGC->info.sliceHeight = PTR_JPGC->info.sliceMbSetValue / 2;
|
else
|
PTR_JPGC->info.sliceHeight = PTR_JPGC->info.sliceMbSetValue;
|
}
|
}
|
|
/*------------------------------------------------------------------------------
|
|
Function name: JpegDecWriteTables
|
|
Functional description:
|
Writes q/ac/dc tables to the HW format as specified in HW regs
|
|
Inputs:
|
JpegDecContainer *pJpegDecCont
|
|
Outputs:
|
void
|
|
------------------------------------------------------------------------------*/
|
static void JpegDecWriteTables(JpegDecContainer * pJpegDecCont)
|
{
|
JpegDecContainer *PTR_JPGC = pJpegDecCont;
|
ScanInfo *JPG_SCN = &pJpegDecCont->scan;
|
HuffmanTables *JPG_VLC = &pJpegDecCont->vlc;
|
QuantTables *JPG_QTB = &pJpegDecCont->quant;
|
FrameInfo *JPG_FRM = &pJpegDecCont->frame;
|
|
RK_U32 i, j = 0;
|
RK_U32 shifter = 32;
|
RK_U32 tableWord = 0;
|
RK_U32 tableValue = 0;
|
RK_U8 tableTmp[64] = { 0 };
|
RK_U32 *pTableBase = NULL;
|
|
ASSERT(PTR_JPGC);
|
ASSERT(PTR_JPGC->frame.pTableBase.vir_addr);
|
ASSERT(PTR_JPGC->frame.pTableBase.phy_addr);
|
ASSERT(PTR_JPGC->frame.pTableBase.size);
|
|
pTableBase = PTR_JPGC->frame.pTableBase.vir_addr;
|
|
/* QP tables for all components */
|
for (j = 0; j < PTR_JPGC->info.amountOfQTables; j++) {
|
if ((JPG_FRM->component[j].Tq) == 0) {
|
for (i = 0; i < 64; i++) {
|
tableTmp[zzOrder[i]] = (RK_U8) JPG_QTB->table0[i];
|
}
|
|
/* update shifter */
|
shifter = 32;
|
|
for (i = 0; i < 64; i++) {
|
shifter -= 8;
|
|
if (shifter == 24)
|
tableWord = (tableTmp[i] << shifter);
|
else
|
tableWord |= (tableTmp[i] << shifter);
|
|
if (shifter == 0) {
|
*(pTableBase) = tableWord;
|
pTableBase++;
|
shifter = 32;
|
}
|
}
|
} else {
|
for (i = 0; i < 64; i++) {
|
tableTmp[zzOrder[i]] = (RK_U8) JPG_QTB->table1[i];
|
}
|
|
/* update shifter */
|
shifter = 32;
|
|
for (i = 0; i < 64; i++) {
|
shifter -= 8;
|
|
if (shifter == 24)
|
tableWord = (tableTmp[i] << shifter);
|
else
|
tableWord |= (tableTmp[i] << shifter);
|
|
if (shifter == 0) {
|
*(pTableBase) = tableWord;
|
pTableBase++;
|
shifter = 32;
|
}
|
}
|
}
|
}
|
|
/* update shifter */
|
shifter = 32;
|
|
if (PTR_JPGC->info.yCbCrMode != JPEGDEC_YUV400) {
|
/* this trick is done because hw always wants luma table as ac hw table 1 */
|
if (JPG_SCN->Ta[0] == 0) {
|
/* Write AC Table 1 (as specified in HW regs)
|
* NOTE: Not the same as actable[1] (as specified in JPEG Spec) */
|
JPEGDEC_TRACE_INTERNAL(("INTERNAL: Write tables: AC1 (luma)\n"));
|
if (JPG_VLC->acTable0.vals) {
|
for (i = 0; i < 162; i++) {
|
if (i < JPG_VLC->acTable0.tableLength) {
|
tableValue = (RK_U8) JPG_VLC->acTable0.vals[i];
|
} else {
|
tableValue = 0;
|
}
|
|
if (shifter == 32)
|
tableWord = (tableValue << (shifter - 8));
|
else
|
tableWord |= (tableValue << (shifter - 8));
|
|
shifter -= 8;
|
|
if (shifter == 0) {
|
*(pTableBase) = tableWord;
|
pTableBase++;
|
shifter = 32;
|
}
|
}
|
} else {
|
for (i = 0; i < 162; i++) {
|
tableWord = 0;
|
|
shifter -= 8;
|
|
if (shifter == 0) {
|
*(pTableBase) = tableWord;
|
pTableBase++;
|
shifter = 32;
|
}
|
}
|
}
|
/* Write AC Table 2 */
|
JPEGDEC_TRACE_INTERNAL(("INTERNAL: Write tables: AC2 (not-luma)\n"));
|
if (JPG_VLC->acTable1.vals) {
|
for (i = 0; i < 162; i++) {
|
if (i < JPG_VLC->acTable1.tableLength) {
|
tableValue = (RK_U8) JPG_VLC->acTable1.vals[i];
|
} else {
|
tableValue = 0;
|
}
|
|
if (shifter == 32)
|
tableWord = (tableValue << (shifter - 8));
|
else
|
tableWord |= (tableValue << (shifter - 8));
|
|
shifter -= 8;
|
|
if (shifter == 0) {
|
*(pTableBase) = tableWord;
|
pTableBase++;
|
shifter = 32;
|
}
|
}
|
} else {
|
for (i = 0; i < 162; i++) {
|
tableWord = 0;
|
|
shifter -= 8;
|
|
if (shifter == 0) {
|
*(pTableBase) = tableWord;
|
pTableBase++;
|
shifter = 32;
|
}
|
}
|
}
|
} else {
|
/* Write AC Table 1 (as specified in HW regs)
|
* NOTE: Not the same as actable[1] (as specified in JPEG Spec) */
|
|
if (JPG_VLC->acTable1.vals) {
|
JPEGDEC_TRACE_INTERNAL(("INTERNAL: Write tables: AC1 (luma)\n"));
|
for (i = 0; i < 162; i++) {
|
if (i < JPG_VLC->acTable1.tableLength) {
|
tableValue = (RK_U8) JPG_VLC->acTable1.vals[i];
|
} else {
|
tableValue = 0;
|
}
|
|
if (shifter == 32)
|
tableWord = (tableValue << (shifter - 8));
|
else
|
tableWord |= (tableValue << (shifter - 8));
|
|
shifter -= 8;
|
|
if (shifter == 0) {
|
*(pTableBase) = tableWord;
|
pTableBase++;
|
shifter = 32;
|
}
|
}
|
} else {
|
for (i = 0; i < 162; i++) {
|
tableWord = 0;
|
|
shifter -= 8;
|
|
if (shifter == 0) {
|
*(pTableBase) = tableWord;
|
pTableBase++;
|
shifter = 32;
|
}
|
}
|
}
|
|
/* Write AC Table 2 */
|
if (JPG_VLC->acTable0.vals) {
|
JPEGDEC_TRACE_INTERNAL(("INTERNAL: writeTables: AC2 (not-luma)\n"));
|
for (i = 0; i < 162; i++) {
|
if (i < JPG_VLC->acTable0.tableLength) {
|
tableValue = (RK_U8) JPG_VLC->acTable0.vals[i];
|
} else {
|
tableValue = 0;
|
}
|
|
if (shifter == 32)
|
tableWord = (tableValue << (shifter - 8));
|
else
|
tableWord |= (tableValue << (shifter - 8));
|
|
shifter -= 8;
|
|
if (shifter == 0) {
|
*(pTableBase) = tableWord;
|
pTableBase++;
|
shifter = 32;
|
}
|
}
|
} else {
|
for (i = 0; i < 162; i++) {
|
tableWord = 0;
|
|
shifter -= 8;
|
|
if (shifter == 0) {
|
*(pTableBase) = tableWord;
|
pTableBase++;
|
shifter = 32;
|
}
|
}
|
}
|
}
|
|
/* this trick is done because hw always wants luma table as dc hw table 1 */
|
if (JPG_SCN->Td[0] == 0) {
|
if (JPG_VLC->dcTable0.vals) {
|
for (i = 0; i < 12; i++) {
|
if (i < JPG_VLC->dcTable0.tableLength) {
|
tableValue = (RK_U8) JPG_VLC->dcTable0.vals[i];
|
} else {
|
tableValue = 0;
|
}
|
|
if (shifter == 32)
|
tableWord = (tableValue << (shifter - 8));
|
else
|
tableWord |= (tableValue << (shifter - 8));
|
|
shifter -= 8;
|
|
if (shifter == 0) {
|
*(pTableBase) = tableWord;
|
pTableBase++;
|
shifter = 32;
|
}
|
}
|
} else {
|
for (i = 0; i < 12; i++) {
|
tableWord = 0;
|
|
shifter -= 8;
|
|
if (shifter == 0) {
|
*(pTableBase) = tableWord;
|
pTableBase++;
|
shifter = 32;
|
}
|
}
|
}
|
|
if (JPG_VLC->dcTable1.vals) {
|
for (i = 0; i < 12; i++) {
|
if (i < JPG_VLC->dcTable1.tableLength) {
|
tableValue = (RK_U8) JPG_VLC->dcTable1.vals[i];
|
} else {
|
tableValue = 0;
|
}
|
|
if (shifter == 32)
|
tableWord = (tableValue << (shifter - 8));
|
else
|
tableWord |= (tableValue << (shifter - 8));
|
|
shifter -= 8;
|
|
if (shifter == 0) {
|
*(pTableBase) = tableWord;
|
pTableBase++;
|
shifter = 32;
|
}
|
}
|
} else {
|
for (i = 0; i < 12; i++) {
|
tableWord = 0;
|
|
shifter -= 8;
|
|
if (shifter == 0) {
|
*(pTableBase) = tableWord;
|
pTableBase++;
|
shifter = 32;
|
}
|
}
|
}
|
|
} else {
|
if (JPG_VLC->dcTable1.vals) {
|
for (i = 0; i < 12; i++) {
|
if (i < JPG_VLC->dcTable1.tableLength) {
|
tableValue = (RK_U8) JPG_VLC->dcTable1.vals[i];
|
} else {
|
tableValue = 0;
|
}
|
|
if (shifter == 32)
|
tableWord = (tableValue << (shifter - 8));
|
else
|
tableWord |= (tableValue << (shifter - 8));
|
|
shifter -= 8;
|
|
if (shifter == 0) {
|
*(pTableBase) = tableWord;
|
pTableBase++;
|
shifter = 32;
|
}
|
}
|
} else {
|
for (i = 0; i < 12; i++) {
|
tableWord = 0;
|
|
shifter -= 8;
|
|
if (shifter == 0) {
|
*(pTableBase) = tableWord;
|
pTableBase++;
|
shifter = 32;
|
}
|
}
|
}
|
|
if (JPG_VLC->dcTable0.vals) {
|
for (i = 0; i < 12; i++) {
|
if (i < JPG_VLC->dcTable0.tableLength) {
|
tableValue = (RK_U8) JPG_VLC->dcTable0.vals[i];
|
} else {
|
tableValue = 0;
|
}
|
|
if (shifter == 32)
|
tableWord = (tableValue << (shifter - 8));
|
else
|
tableWord |= (tableValue << (shifter - 8));
|
|
shifter -= 8;
|
|
if (shifter == 0) {
|
*(pTableBase) = tableWord;
|
pTableBase++;
|
shifter = 32;
|
}
|
}
|
} else {
|
for (i = 0; i < 12; i++) {
|
tableWord = 0;
|
|
shifter -= 8;
|
|
if (shifter == 0) {
|
*(pTableBase) = tableWord;
|
pTableBase++;
|
shifter = 32;
|
}
|
}
|
}
|
}
|
} else { /* YUV400 */
|
if (!PTR_JPGC->info.nonInterleavedScanReady) {
|
/* this trick is done because hw always wants luma table as ac hw table 1 */
|
if (JPG_SCN->Ta[0] == 0) {
|
/* Write AC Table 1 (as specified in HW regs)
|
* NOTE: Not the same as actable[1] (as specified in JPEG Spec) */
|
JPEGDEC_TRACE_INTERNAL(("INTERNAL: Write tables: AC1 (luma)\n"));
|
if (JPG_VLC->acTable0.vals) {
|
for (i = 0; i < 162; i++) {
|
if (i < JPG_VLC->acTable0.tableLength) {
|
tableValue = (RK_U8) JPG_VLC->acTable0.vals[i];
|
} else {
|
tableValue = 0;
|
}
|
|
if (shifter == 32)
|
tableWord = (tableValue << (shifter - 8));
|
else
|
tableWord |= (tableValue << (shifter - 8));
|
|
shifter -= 8;
|
|
if (shifter == 0) {
|
*(pTableBase) = tableWord;
|
pTableBase++;
|
shifter = 32;
|
}
|
}
|
} else {
|
for (i = 0; i < 162; i++) {
|
tableWord = 0;
|
|
shifter -= 8;
|
|
if (shifter == 0) {
|
*(pTableBase) = tableWord;
|
pTableBase++;
|
shifter = 32;
|
}
|
}
|
}
|
|
/* Write AC Table 2 */
|
JPEGDEC_TRACE_INTERNAL(("INTERNAL: Write zero table (YUV400): \n"));
|
for (i = 0; i < 162; i++) {
|
tableValue = 0;
|
|
if (shifter == 32)
|
tableWord = (tableValue << (shifter - 8));
|
else
|
tableWord |= (tableValue << (shifter - 8));
|
|
shifter -= 8;
|
|
if (shifter == 0) {
|
*(pTableBase) = tableWord;
|
pTableBase++;
|
shifter = 32;
|
}
|
}
|
} else {
|
/* Write AC Table 1 (as specified in HW regs)
|
* NOTE: Not the same as actable[1] (as specified in JPEG Spec) */
|
|
if (JPG_VLC->acTable1.vals) {
|
JPEGDEC_TRACE_INTERNAL(("INTERNAL: Write tables: AC1 (luma)\n"));
|
for (i = 0; i < 162; i++) {
|
if (i < JPG_VLC->acTable1.tableLength) {
|
tableValue = (RK_U8) JPG_VLC->acTable1.vals[i];
|
} else {
|
tableValue = 0;
|
}
|
|
if (shifter == 32)
|
tableWord = (tableValue << (shifter - 8));
|
else
|
tableWord |= (tableValue << (shifter - 8));
|
|
shifter -= 8;
|
|
if (shifter == 0) {
|
*(pTableBase) = tableWord;
|
pTableBase++;
|
shifter = 32;
|
}
|
}
|
} else {
|
for (i = 0; i < 162; i++) {
|
tableWord = 0;
|
|
shifter -= 8;
|
|
if (shifter == 0) {
|
*(pTableBase) = tableWord;
|
pTableBase++;
|
shifter = 32;
|
}
|
}
|
}
|
|
/* Write AC Table 2 */
|
JPEGDEC_TRACE_INTERNAL(("INTERNAL: writeTables: padding zero (YUV400)\n"));
|
for (i = 0; i < 162; i++) {
|
tableValue = 0;
|
|
if (shifter == 32)
|
tableWord = (tableValue << (shifter - 8));
|
else
|
tableWord |= (tableValue << (shifter - 8));
|
|
shifter -= 8;
|
|
if (shifter == 0) {
|
*(pTableBase) = tableWord;
|
pTableBase++;
|
shifter = 32;
|
}
|
}
|
}
|
|
/* this trick is done because hw always wants luma table as dc hw table 1 */
|
if (JPG_SCN->Td[0] == 0) {
|
if (JPG_VLC->dcTable0.vals) {
|
for (i = 0; i < 12; i++) {
|
if (i < JPG_VLC->dcTable0.tableLength) {
|
tableValue = (RK_U8) JPG_VLC->dcTable0.vals[i];
|
} else {
|
tableValue = 0;
|
}
|
|
if (shifter == 32)
|
tableWord = (tableValue << (shifter - 8));
|
else
|
tableWord |= (tableValue << (shifter - 8));
|
|
shifter -= 8;
|
|
if (shifter == 0) {
|
*(pTableBase) = tableWord;
|
pTableBase++;
|
shifter = 32;
|
}
|
}
|
} else {
|
for (i = 0; i < 12; i++) {
|
tableWord = 0;
|
|
shifter -= 8;
|
|
if (shifter == 0) {
|
*(pTableBase) = tableWord;
|
pTableBase++;
|
shifter = 32;
|
}
|
}
|
}
|
|
for (i = 0; i < 12; i++) {
|
tableValue = 0;
|
|
if (shifter == 32)
|
tableWord = (tableValue << (shifter - 8));
|
else
|
tableWord |= (tableValue << (shifter - 8));
|
|
shifter -= 8;
|
|
if (shifter == 0) {
|
*(pTableBase) = tableWord;
|
pTableBase++;
|
shifter = 32;
|
}
|
}
|
} else {
|
if (JPG_VLC->dcTable1.vals) {
|
for (i = 0; i < 12; i++) {
|
if (i < JPG_VLC->dcTable1.tableLength) {
|
tableValue = (RK_U8) JPG_VLC->dcTable1.vals[i];
|
} else {
|
tableValue = 0;
|
}
|
|
if (shifter == 32)
|
tableWord = (tableValue << (shifter - 8));
|
else
|
tableWord |= (tableValue << (shifter - 8));
|
|
shifter -= 8;
|
|
if (shifter == 0) {
|
*(pTableBase) = tableWord;
|
pTableBase++;
|
shifter = 32;
|
}
|
}
|
} else {
|
for (i = 0; i < 12; i++) {
|
tableWord = 0;
|
|
shifter -= 8;
|
|
if (shifter == 0) {
|
*(pTableBase) = tableWord;
|
pTableBase++;
|
shifter = 32;
|
}
|
}
|
}
|
|
for (i = 0; i < 12; i++) {
|
tableValue = 0;
|
|
if (shifter == 32)
|
tableWord = (tableValue << (shifter - 8));
|
else
|
tableWord |= (tableValue << (shifter - 8));
|
|
shifter -= 8;
|
|
if (shifter == 0) {
|
*(pTableBase) = tableWord;
|
pTableBase++;
|
shifter = 32;
|
}
|
}
|
}
|
} else {
|
|
/* this trick is done because hw always wants luma table as ac hw table 1 */
|
if (JPG_SCN->Ta[PTR_JPGC->info.componentId] == 0) {
|
/* Write AC Table 1 (as specified in HW regs)
|
* NOTE: Not the same as actable[1] (as specified in JPEG Spec) */
|
JPEGDEC_TRACE_INTERNAL(("INTERNAL: Write tables: AC1 (luma)\n"));
|
if (JPG_VLC->acTable0.vals) {
|
for (i = 0; i < 162; i++) {
|
if (i < JPG_VLC->acTable0.tableLength) {
|
tableValue = (RK_U8) JPG_VLC->acTable0.vals[i];
|
} else {
|
tableValue = 0;
|
}
|
|
if (shifter == 32)
|
tableWord = (tableValue << (shifter - 8));
|
else
|
tableWord |= (tableValue << (shifter - 8));
|
|
shifter -= 8;
|
|
if (shifter == 0) {
|
*(pTableBase) = tableWord;
|
pTableBase++;
|
shifter = 32;
|
}
|
}
|
} else {
|
for (i = 0; i < 162; i++) {
|
tableWord = 0;
|
|
shifter -= 8;
|
|
if (shifter == 0) {
|
*(pTableBase) = tableWord;
|
pTableBase++;
|
shifter = 32;
|
}
|
}
|
}
|
|
/* Write AC Table 2 */
|
JPEGDEC_TRACE_INTERNAL(("INTERNAL: Write zero table (YUV400): \n"));
|
for (i = 0; i < 162; i++) {
|
tableValue = 0;
|
|
if (shifter == 32)
|
tableWord = (tableValue << (shifter - 8));
|
else
|
tableWord |= (tableValue << (shifter - 8));
|
|
shifter -= 8;
|
|
if (shifter == 0) {
|
*(pTableBase) = tableWord;
|
pTableBase++;
|
shifter = 32;
|
}
|
}
|
} else {
|
/* Write AC Table 1 (as specified in HW regs)
|
* NOTE: Not the same as actable[1] (as specified in JPEG Spec) */
|
|
if (JPG_VLC->acTable1.vals) {
|
JPEGDEC_TRACE_INTERNAL(("INTERNAL: Write tables: AC1 (luma)\n"));
|
for (i = 0; i < 162; i++) {
|
if (i < JPG_VLC->acTable1.tableLength) {
|
tableValue = (RK_U8) JPG_VLC->acTable1.vals[i];
|
} else {
|
tableValue = 0;
|
}
|
|
if (shifter == 32)
|
tableWord = (tableValue << (shifter - 8));
|
else
|
tableWord |= (tableValue << (shifter - 8));
|
|
shifter -= 8;
|
|
if (shifter == 0) {
|
*(pTableBase) = tableWord;
|
pTableBase++;
|
shifter = 32;
|
}
|
}
|
} else {
|
for (i = 0; i < 162; i++) {
|
tableWord = 0;
|
|
shifter -= 8;
|
|
if (shifter == 0) {
|
*(pTableBase) = tableWord;
|
pTableBase++;
|
shifter = 32;
|
}
|
}
|
}
|
|
/* Write AC Table 2 */
|
JPEGDEC_TRACE_INTERNAL(("INTERNAL: writeTables: padding zero (YUV400)\n"));
|
for (i = 0; i < 162; i++) {
|
tableValue = 0;
|
|
if (shifter == 32)
|
tableWord = (tableValue << (shifter - 8));
|
else
|
tableWord |= (tableValue << (shifter - 8));
|
|
shifter -= 8;
|
|
if (shifter == 0) {
|
*(pTableBase) = tableWord;
|
pTableBase++;
|
shifter = 32;
|
}
|
}
|
}
|
|
/* this trick is done because hw always wants luma table as dc hw table 1 */
|
if (JPG_SCN->Td[PTR_JPGC->info.componentId] == 0) {
|
if (JPG_VLC->dcTable0.vals) {
|
for (i = 0; i < 12; i++) {
|
if (i < JPG_VLC->dcTable0.tableLength) {
|
tableValue = (RK_U8) JPG_VLC->dcTable0.vals[i];
|
} else {
|
tableValue = 0;
|
}
|
|
if (shifter == 32)
|
tableWord = (tableValue << (shifter - 8));
|
else
|
tableWord |= (tableValue << (shifter - 8));
|
|
shifter -= 8;
|
|
if (shifter == 0) {
|
*(pTableBase) = tableWord;
|
pTableBase++;
|
shifter = 32;
|
}
|
}
|
} else {
|
for (i = 0; i < 12; i++) {
|
tableWord = 0;
|
|
shifter -= 8;
|
|
if (shifter == 0) {
|
*(pTableBase) = tableWord;
|
pTableBase++;
|
shifter = 32;
|
}
|
}
|
}
|
|
for (i = 0; i < 12; i++) {
|
tableValue = 0;
|
|
if (shifter == 32)
|
tableWord = (tableValue << (shifter - 8));
|
else
|
tableWord |= (tableValue << (shifter - 8));
|
|
shifter -= 8;
|
|
if (shifter == 0) {
|
*(pTableBase) = tableWord;
|
pTableBase++;
|
shifter = 32;
|
}
|
}
|
} else {
|
if (JPG_VLC->dcTable1.vals) {
|
for (i = 0; i < 12; i++) {
|
if (i < JPG_VLC->dcTable1.tableLength) {
|
tableValue = (RK_U8) JPG_VLC->dcTable1.vals[i];
|
} else {
|
tableValue = 0;
|
}
|
|
if (shifter == 32)
|
tableWord = (tableValue << (shifter - 8));
|
else
|
tableWord |= (tableValue << (shifter - 8));
|
|
shifter -= 8;
|
|
if (shifter == 0) {
|
*(pTableBase) = tableWord;
|
pTableBase++;
|
shifter = 32;
|
}
|
}
|
} else {
|
for (i = 0; i < 12; i++) {
|
tableWord = 0;
|
|
shifter -= 8;
|
|
if (shifter == 0) {
|
*(pTableBase) = tableWord;
|
pTableBase++;
|
shifter = 32;
|
}
|
}
|
}
|
|
for (i = 0; i < 12; i++) {
|
tableValue = 0;
|
|
if (shifter == 32)
|
tableWord = (tableValue << (shifter - 8));
|
else
|
tableWord |= (tableValue << (shifter - 8));
|
|
shifter -= 8;
|
|
if (shifter == 0) {
|
*(pTableBase) = tableWord;
|
pTableBase++;
|
shifter = 32;
|
}
|
}
|
}
|
}
|
|
}
|
|
for (i = 0; i < 4; i++) {
|
tableValue = 0;
|
|
if (shifter == 32)
|
tableWord = (tableValue << (shifter - 8));
|
else
|
tableWord |= (tableValue << (shifter - 8));
|
|
shifter -= 8;
|
|
if (shifter == 0) {
|
*(pTableBase) = tableWord;
|
pTableBase++;
|
shifter = 32;
|
}
|
}
|
|
}
|
|
/*------------------------------------------------------------------------------
|
Function name: JpegDecWriteTablesNonInterleaved
|
|
Functional description:
|
Writes q/ac/dc tables to the HW format as specified in HW regs
|
|
Inputs:
|
JpegDecContainer *pJpegDecCont
|
|
Outputs:
|
void
|
|
------------------------------------------------------------------------------*/
|
static void JpegDecWriteTablesNonInterleaved(JpegDecContainer * pJpegDecCont)
|
{
|
|
JpegDecContainer *PTR_JPGC = pJpegDecCont;
|
ScanInfo *JPG_SCN = &pJpegDecCont->scan;
|
HuffmanTables *JPG_VLC = &pJpegDecCont->vlc;
|
QuantTables *JPG_QTB = &pJpegDecCont->quant;
|
FrameInfo *JPG_FRM = &pJpegDecCont->frame;
|
|
RK_U32 i, j = 0;
|
RK_U32 tableWord = 0;
|
RK_U8 tableTmp[64] = { 0 };
|
RK_U8 *pTmp;
|
RK_U32 *pTableBase = NULL;
|
RK_U32 first, count;
|
RK_U32 len, numWords;
|
RK_U32 *vals;
|
RK_U32 *pTable;
|
RK_U32 dcTable = 0;
|
RK_U32 qpTableBase = 0;
|
|
ASSERT(PTR_JPGC);
|
ASSERT(PTR_JPGC->frame.pTableBase.vir_addr);
|
ASSERT(PTR_JPGC->frame.pTableBase.phy_addr);
|
ASSERT(PTR_JPGC->frame.pTableBase.size);
|
ASSERT(PTR_JPGC->info.nonInterleaved);
|
|
/* Reset the table memory */
|
(void) DWLmemset(PTR_JPGC->frame.pTableBase.vir_addr, 0,
|
(sizeof(RK_U8) * JPEGDEC_BASELINE_TABLE_SIZE));
|
|
pTableBase = PTR_JPGC->frame.pTableBase.vir_addr;
|
|
first = PTR_JPGC->info.componentId;
|
count = 1;
|
|
/* QP tables for all components */
|
for (j = first; j < first + count; j++) {
|
if ((JPG_FRM->component[j].Tq) == 0)
|
pTable = JPG_QTB->table0;
|
else
|
pTable = JPG_QTB->table1;
|
|
for (i = 0; i < 64; i++) {
|
tableTmp[zzOrder[i]] = (RK_U8) pTable[i];
|
}
|
|
pTmp = tableTmp;
|
for (i = 0; i < 16; i++) {
|
tableWord = (pTmp[0] << 24) | (pTmp[1] << 16) |
|
(pTmp[2] << 8) | (pTmp[3] << 0);;
|
|
*pTableBase++ = tableWord;
|
pTmp += 4;
|
}
|
}
|
|
/* AC table */
|
for (i = first; i < first + count; i++) {
|
numWords = 162;
|
switch (JPG_SCN->Ta[i]) {
|
case 0:
|
vals = JPG_VLC->acTable0.vals;
|
len = JPG_VLC->acTable0.tableLength;
|
break;
|
case 1:
|
vals = JPG_VLC->acTable1.vals;
|
len = JPG_VLC->acTable1.tableLength;
|
break;
|
case 2:
|
vals = JPG_VLC->acTable2.vals;
|
len = JPG_VLC->acTable2.tableLength;
|
break;
|
default:
|
vals = JPG_VLC->acTable3.vals;
|
len = JPG_VLC->acTable3.tableLength;
|
break;
|
}
|
|
/* set pointer */
|
if (count == 3)
|
qpTableBase = 0;
|
else
|
qpTableBase = JPEGDEC_QP_BASE;
|
|
pTableBase =
|
&PTR_JPGC->frame.pTableBase.vir_addr[JPEGDEC_AC1_BASE -
|
qpTableBase];
|
|
for (j = 0; j < numWords; j++) {
|
tableWord <<= 8;
|
if (j < len)
|
tableWord |= vals[j];
|
|
if ((j & 0x3) == 0x3)
|
*pTableBase++ = tableWord;
|
}
|
|
/* fill to border */
|
numWords = 164;
|
len = 164;
|
for (j = 162; j < numWords; j++) {
|
tableWord <<= 8;
|
if (j < len)
|
tableWord |= 0;
|
|
if ((j & 0x3) == 0x3)
|
*pTableBase++ = tableWord;
|
}
|
}
|
|
/* DC table */
|
for (i = first; i < first + count; i++) {
|
numWords = 12;
|
switch (JPG_SCN->Td[i]) {
|
case 0:
|
vals = JPG_VLC->dcTable0.vals;
|
len = JPG_VLC->dcTable0.tableLength;
|
break;
|
case 1:
|
vals = JPG_VLC->dcTable1.vals;
|
len = JPG_VLC->dcTable1.tableLength;
|
break;
|
case 2:
|
vals = JPG_VLC->dcTable2.vals;
|
len = JPG_VLC->dcTable2.tableLength;
|
break;
|
default:
|
vals = JPG_VLC->dcTable3.vals;
|
len = JPG_VLC->dcTable3.tableLength;
|
break;
|
}
|
|
/* set pointer */
|
if (count == 3)
|
qpTableBase = 0;
|
else
|
qpTableBase = JPEGDEC_QP_BASE;
|
|
pTableBase =
|
&PTR_JPGC->frame.pTableBase.vir_addr[JPEGDEC_DC1_BASE -
|
qpTableBase];
|
|
for (j = 0; j < numWords; j++) {
|
tableWord <<= 8;
|
if (j < len)
|
tableWord |= vals[j];
|
|
if ((j & 0x3) == 0x3)
|
*pTableBase++ = tableWord;
|
}
|
}
|
|
*pTableBase = 0;
|
}
|
|
/*------------------------------------------------------------------------------
|
|
Function name: JpegDecWriteTablesProgressive
|
|
Functional description:
|
Writes q/ac/dc tables to the HW format as specified in HW regs
|
|
Inputs:
|
JpegDecContainer *pJpegDecCont
|
|
Outputs:
|
void
|
|
------------------------------------------------------------------------------*/
|
static void JpegDecWriteTablesProgressive(JpegDecContainer * pJpegDecCont)
|
{
|
JpegDecContainer *PTR_JPGC = pJpegDecCont;
|
ScanInfo *JPG_SCN = &pJpegDecCont->scan;
|
HuffmanTables *JPG_VLC = &pJpegDecCont->vlc;
|
QuantTables *JPG_QTB = &pJpegDecCont->quant;
|
FrameInfo *JPG_FRM = &pJpegDecCont->frame;
|
|
RK_U32 i, j = 0;
|
RK_U32 tableWord = 0;
|
RK_U8 tableTmp[64] = { 0 };
|
RK_U8 *pTmp;
|
RK_U32 *pTableBase = NULL;
|
RK_U32 first, count;
|
RK_U32 len, numWords;
|
RK_U32 *vals;
|
RK_U32 *pTable;
|
RK_U32 dcTable = 0;
|
RK_U32 qpTableBase = 0;
|
|
ASSERT(PTR_JPGC);
|
ASSERT(PTR_JPGC->frame.pTableBase.vir_addr);
|
ASSERT(PTR_JPGC->frame.pTableBase.phy_addr);
|
ASSERT(PTR_JPGC->frame.pTableBase.size);
|
|
/* Reset the table memory */
|
(void) DWLmemset(PTR_JPGC->frame.pTableBase.vir_addr, 0,
|
(sizeof(RK_U8) * JPEGDEC_PROGRESSIVE_TABLE_SIZE));
|
|
pTableBase = PTR_JPGC->frame.pTableBase.vir_addr;
|
|
if (PTR_JPGC->info.nonInterleaved) {
|
first = PTR_JPGC->info.componentId;
|
count = 1;
|
} else {
|
first = 0;
|
count = 3;
|
}
|
|
/* QP tables for all components */
|
for (j = first; j < first + count; j++) {
|
if ((JPG_FRM->component[j].Tq) == 0)
|
pTable = JPG_QTB->table0;
|
else
|
pTable = JPG_QTB->table1;
|
|
for (i = 0; i < 64; i++) {
|
tableTmp[zzOrder[i]] = (RK_U8) pTable[i];
|
}
|
|
pTmp = tableTmp;
|
for (i = 0; i < 16; i++) {
|
tableWord = (pTmp[0] << 24) | (pTmp[1] << 16) |
|
(pTmp[2] << 8) | (pTmp[3] << 0);;
|
|
*pTableBase++ = tableWord;
|
pTmp += 4;
|
}
|
}
|
|
/* if later stage DC ==> no need for table */
|
if (PTR_JPGC->scan.Ah != 0 && PTR_JPGC->scan.Ss == 0)
|
return;
|
|
for (i = first; i < first + count; i++) {
|
if (PTR_JPGC->scan.Ss == 0) { /* DC */
|
dcTable = 1;
|
numWords = 12;
|
switch (JPG_SCN->Td[i]) {
|
case 0:
|
vals = JPG_VLC->dcTable0.vals;
|
len = JPG_VLC->dcTable0.tableLength;
|
break;
|
case 1:
|
vals = JPG_VLC->dcTable1.vals;
|
len = JPG_VLC->dcTable1.tableLength;
|
break;
|
case 2:
|
vals = JPG_VLC->dcTable2.vals;
|
len = JPG_VLC->dcTable2.tableLength;
|
break;
|
default:
|
vals = JPG_VLC->dcTable3.vals;
|
len = JPG_VLC->dcTable3.tableLength;
|
break;
|
}
|
} else {
|
numWords = 162;
|
switch (JPG_SCN->Ta[i]) {
|
case 0:
|
vals = JPG_VLC->acTable0.vals;
|
len = JPG_VLC->acTable0.tableLength;
|
break;
|
case 1:
|
vals = JPG_VLC->acTable1.vals;
|
len = JPG_VLC->acTable1.tableLength;
|
break;
|
case 2:
|
vals = JPG_VLC->acTable2.vals;
|
len = JPG_VLC->acTable2.tableLength;
|
break;
|
default:
|
vals = JPG_VLC->acTable3.vals;
|
len = JPG_VLC->acTable3.tableLength;
|
break;
|
}
|
}
|
|
/* set pointer */
|
if (count == 3)
|
qpTableBase = 0;
|
else
|
qpTableBase = JPEGDEC_QP_BASE;
|
|
if (dcTable) {
|
/* interleaved || non-interleaved */
|
if (count == 3) {
|
if (i == 0)
|
pTableBase =
|
&PTR_JPGC->frame.pTableBase.
|
vir_addr[JPEGDEC_DC1_BASE - qpTableBase];
|
else if (i == 1)
|
pTableBase =
|
&PTR_JPGC->frame.pTableBase.
|
vir_addr[JPEGDEC_DC2_BASE - qpTableBase];
|
else
|
pTableBase =
|
&PTR_JPGC->frame.pTableBase.
|
vir_addr[JPEGDEC_DC3_BASE - qpTableBase];
|
} else {
|
pTableBase =
|
&PTR_JPGC->frame.pTableBase.
|
vir_addr[JPEGDEC_DC1_BASE - qpTableBase];
|
}
|
} else {
|
pTableBase =
|
&PTR_JPGC->frame.pTableBase.vir_addr[JPEGDEC_AC1_BASE -
|
qpTableBase];
|
}
|
|
for (j = 0; j < numWords; j++) {
|
tableWord <<= 8;
|
if (j < len)
|
tableWord |= vals[j];
|
|
if ((j & 0x3) == 0x3)
|
*pTableBase++ = tableWord;
|
}
|
|
/* fill to border */
|
if (i == 0 && dcTable == 0) {
|
numWords = 164;
|
len = 164;
|
for (j = 162; j < numWords; j++) {
|
tableWord <<= 8;
|
if (j < len)
|
tableWord |= 0;
|
|
if ((j & 0x3) == 0x3)
|
*pTableBase++ = tableWord;
|
}
|
}
|
|
/* reset */
|
dcTable = 0;
|
}
|
|
*pTableBase = 0;
|
}
|
|
/*------------------------------------------------------------------------------
|
|
Function name: JpegDecChromaTableSelectors
|
|
Functional description:
|
select what tables chromas use
|
|
Inputs:
|
JpegDecContainer *pJpegDecCont
|
|
Outputs:
|
void
|
|
------------------------------------------------------------------------------*/
|
static void JpegDecChromaTableSelectors(JpegDecContainer * pJpegDecCont)
|
{
|
JpegDecContainer *PTR_JPGC = pJpegDecCont;
|
ScanInfo *JPG_SCN = &pJpegDecCont->scan;
|
FrameInfo *JPG_FRM = &pJpegDecCont->frame;
|
|
/* this trick is done because hw always wants luma table as ac hw table 1 */
|
if (JPG_SCN->Ta[0] == 0) {
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_CR_AC_VLCTABLE, JPG_SCN->Ta[2]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_CB_AC_VLCTABLE, JPG_SCN->Ta[1]);
|
} else {
|
if (JPG_SCN->Ta[0] == JPG_SCN->Ta[1])
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_CB_AC_VLCTABLE, 0);
|
else
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_CB_AC_VLCTABLE, 1);
|
|
if (JPG_SCN->Ta[0] == JPG_SCN->Ta[2])
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_CR_AC_VLCTABLE, 0);
|
else
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_CR_AC_VLCTABLE, 1);
|
}
|
|
/* Third DC table selectors */
|
if (PTR_JPGC->info.operationType != JPEGDEC_PROGRESSIVE) {
|
if (JPG_SCN->Td[0] == 0) {
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_CR_DC_VLCTABLE,
|
JPG_SCN->Td[2]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_CB_DC_VLCTABLE,
|
JPG_SCN->Td[1]);
|
} else {
|
if (JPG_SCN->Td[0] == JPG_SCN->Td[1])
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_CB_DC_VLCTABLE, 0);
|
else
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_CB_DC_VLCTABLE, 1);
|
|
if (JPG_SCN->Td[0] == JPG_SCN->Td[2])
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_CR_DC_VLCTABLE, 0);
|
else
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_CR_DC_VLCTABLE, 1);
|
}
|
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_CR_DC_VLCTABLE3, 0);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_CB_DC_VLCTABLE3, 0);
|
} else {
|
/* if non-interleaved ==> decoding mode YUV400, uses table zero (0) */
|
if (PTR_JPGC->info.nonInterleaved) {
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_CR_DC_VLCTABLE, 0);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_CB_DC_VLCTABLE, 0);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_CR_DC_VLCTABLE3, 0);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_CB_DC_VLCTABLE3, 0);
|
} else {
|
/* if later stage DC ==> no need for table */
|
if (PTR_JPGC->scan.Ah != 0 && PTR_JPGC->scan.Ss == 0) {
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_CR_DC_VLCTABLE, 0);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_CR_DC_VLCTABLE3, 0);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_CB_DC_VLCTABLE, 0);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_CB_DC_VLCTABLE3, 0);
|
} else {
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_CR_DC_VLCTABLE, 0);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_CR_DC_VLCTABLE3, 1);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_CB_DC_VLCTABLE, 1);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_CB_DC_VLCTABLE3, 0);
|
}
|
}
|
}
|
|
return;
|
}
|
|
/*------------------------------------------------------------------------------
|
|
Function name: JpegDecWriteLenBits
|
|
Functional description:
|
tell hw how many vlc words of different lengths we have
|
|
Inputs:
|
JpegDecContainer *pJpegDecCont
|
|
Outputs:
|
void
|
|
------------------------------------------------------------------------------*/
|
static void JpegDecWriteLenBits(JpegDecContainer * pJpegDecCont)
|
{
|
JpegDecContainer *PTR_JPGC = pJpegDecCont;
|
ScanInfo *JPG_SCN = &pJpegDecCont->scan;
|
HuffmanTables *JPG_VLC = &pJpegDecCont->vlc;
|
QuantTables *JPG_QTB = &pJpegDecCont->quant;
|
FrameInfo *JPG_FRM = &pJpegDecCont->frame;
|
|
VlcTable *pTable1 = NULL;
|
VlcTable *pTable2 = NULL;
|
|
/* first select the table we'll use */
|
/* this trick is done because hw always wants luma table as ac hw table 1 */
|
if (JPG_SCN->Ta[0] == 0) {
|
|
pTable1 = &(JPG_VLC->acTable0);
|
pTable2 = &(JPG_VLC->acTable1);
|
|
} else {
|
|
pTable1 = &(JPG_VLC->acTable1);
|
pTable2 = &(JPG_VLC->acTable0);
|
}
|
|
ASSERT(pTable1);
|
ASSERT(pTable2);
|
|
/* write AC table 1 (luma) */
|
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_AC1_CODE1_CNT, pTable1->bits[0]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_AC1_CODE2_CNT, pTable1->bits[1]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_AC1_CODE3_CNT, pTable1->bits[2]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_AC1_CODE4_CNT, pTable1->bits[3]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_AC1_CODE5_CNT, pTable1->bits[4]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_AC1_CODE6_CNT, pTable1->bits[5]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_AC1_CODE7_CNT, pTable1->bits[6]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_AC1_CODE8_CNT, pTable1->bits[7]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_AC1_CODE9_CNT, pTable1->bits[8]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_AC1_CODE10_CNT, pTable1->bits[9]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_AC1_CODE11_CNT, pTable1->bits[10]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_AC1_CODE12_CNT, pTable1->bits[11]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_AC1_CODE13_CNT, pTable1->bits[12]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_AC1_CODE14_CNT, pTable1->bits[13]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_AC1_CODE15_CNT, pTable1->bits[14]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_AC1_CODE16_CNT, pTable1->bits[15]);
|
|
/* table AC2 (the not-luma table) */
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_AC2_CODE1_CNT, pTable2->bits[0]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_AC2_CODE2_CNT, pTable2->bits[1]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_AC2_CODE3_CNT, pTable2->bits[2]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_AC2_CODE4_CNT, pTable2->bits[3]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_AC2_CODE5_CNT, pTable2->bits[4]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_AC2_CODE6_CNT, pTable2->bits[5]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_AC2_CODE7_CNT, pTable2->bits[6]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_AC2_CODE8_CNT, pTable2->bits[7]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_AC2_CODE9_CNT, pTable2->bits[8]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_AC2_CODE10_CNT, pTable2->bits[9]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_AC2_CODE11_CNT, pTable2->bits[10]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_AC2_CODE12_CNT, pTable2->bits[11]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_AC2_CODE13_CNT, pTable2->bits[12]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_AC2_CODE14_CNT, pTable2->bits[13]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_AC2_CODE15_CNT, pTable2->bits[14]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_AC2_CODE16_CNT, pTable2->bits[15]);
|
|
if (JPG_SCN->Td[0] == 0) {
|
|
pTable1 = &(JPG_VLC->dcTable0);
|
pTable2 = &(JPG_VLC->dcTable1);
|
|
} else {
|
|
pTable1 = &(JPG_VLC->dcTable1);
|
pTable2 = &(JPG_VLC->dcTable0);
|
}
|
|
ASSERT(pTable1);
|
ASSERT(pTable2);
|
|
/* write DC table 1 (luma) */
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC1_CODE1_CNT, pTable1->bits[0]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC1_CODE2_CNT, pTable1->bits[1]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC1_CODE3_CNT, pTable1->bits[2]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC1_CODE4_CNT, pTable1->bits[3]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC1_CODE5_CNT, pTable1->bits[4]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC1_CODE6_CNT, pTable1->bits[5]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC1_CODE7_CNT, pTable1->bits[6]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC1_CODE8_CNT, pTable1->bits[7]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC1_CODE9_CNT, pTable1->bits[8]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC1_CODE10_CNT, pTable1->bits[9]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC1_CODE11_CNT, pTable1->bits[10]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC1_CODE12_CNT, pTable1->bits[11]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC1_CODE13_CNT, pTable1->bits[12]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC1_CODE14_CNT, pTable1->bits[13]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC1_CODE15_CNT, pTable1->bits[14]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC1_CODE16_CNT, pTable1->bits[15]);
|
|
/* table DC2 (the not-luma table) */
|
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC2_CODE1_CNT, pTable2->bits[0]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC2_CODE2_CNT, pTable2->bits[1]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC2_CODE3_CNT, pTable2->bits[2]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC2_CODE4_CNT, pTable2->bits[3]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC2_CODE5_CNT, pTable2->bits[4]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC2_CODE6_CNT, pTable2->bits[5]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC2_CODE7_CNT, pTable2->bits[6]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC2_CODE8_CNT, pTable2->bits[7]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC2_CODE9_CNT, pTable2->bits[8]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC2_CODE10_CNT, pTable2->bits[9]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC2_CODE11_CNT, pTable2->bits[10]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC2_CODE12_CNT, pTable2->bits[11]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC2_CODE13_CNT, pTable2->bits[12]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC2_CODE14_CNT, pTable2->bits[13]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC2_CODE15_CNT, pTable2->bits[14]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC2_CODE16_CNT, pTable2->bits[15]);
|
|
return;
|
}
|
|
/*------------------------------------------------------------------------------
|
|
Function name: JpegDecWriteLenBitsNonInterleaved
|
|
Functional description:
|
tell hw how many vlc words of different lengths we have
|
|
Inputs:
|
JpegDecContainer *pJpegDecCont
|
|
Outputs:
|
void
|
|
------------------------------------------------------------------------------*/
|
static void JpegDecWriteLenBitsNonInterleaved(JpegDecContainer * pJpegDecCont)
|
{
|
JpegDecContainer *PTR_JPGC = pJpegDecCont;
|
ScanInfo *JPG_SCN = &pJpegDecCont->scan;
|
HuffmanTables *JPG_VLC = &pJpegDecCont->vlc;
|
QuantTables *JPG_QTB = &pJpegDecCont->quant;
|
FrameInfo *JPG_FRM = &pJpegDecCont->frame;
|
|
VlcTable *pTable1 = NULL;
|
VlcTable *pTable2 = NULL;
|
|
/* first select the table we'll use */
|
|
/* this trick is done because hw always wants luma table as ac hw table 1 */
|
if (JPG_SCN->Ta[PTR_JPGC->info.componentId] == 0) {
|
|
pTable1 = &(JPG_VLC->acTable0);
|
pTable2 = &(JPG_VLC->acTable1);
|
|
} else {
|
|
pTable1 = &(JPG_VLC->acTable1);
|
pTable2 = &(JPG_VLC->acTable0);
|
}
|
|
ASSERT(pTable1);
|
ASSERT(pTable2);
|
|
/* write AC table 1 (luma) */
|
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_AC1_CODE1_CNT, pTable1->bits[0]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_AC1_CODE2_CNT, pTable1->bits[1]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_AC1_CODE3_CNT, pTable1->bits[2]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_AC1_CODE4_CNT, pTable1->bits[3]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_AC1_CODE5_CNT, pTable1->bits[4]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_AC1_CODE6_CNT, pTable1->bits[5]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_AC1_CODE7_CNT, pTable1->bits[6]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_AC1_CODE8_CNT, pTable1->bits[7]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_AC1_CODE9_CNT, pTable1->bits[8]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_AC1_CODE10_CNT, pTable1->bits[9]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_AC1_CODE11_CNT, pTable1->bits[10]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_AC1_CODE12_CNT, pTable1->bits[11]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_AC1_CODE13_CNT, pTable1->bits[12]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_AC1_CODE14_CNT, pTable1->bits[13]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_AC1_CODE15_CNT, pTable1->bits[14]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_AC1_CODE16_CNT, pTable1->bits[15]);
|
|
if (JPG_SCN->Td[PTR_JPGC->info.componentId] == 0) {
|
|
pTable1 = &(JPG_VLC->dcTable0);
|
pTable2 = &(JPG_VLC->dcTable1);
|
|
} else {
|
|
pTable1 = &(JPG_VLC->dcTable1);
|
pTable2 = &(JPG_VLC->dcTable0);
|
}
|
|
ASSERT(pTable1);
|
ASSERT(pTable2);
|
|
/* write DC table 1 (luma) */
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC1_CODE1_CNT, pTable1->bits[0]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC1_CODE2_CNT, pTable1->bits[1]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC1_CODE3_CNT, pTable1->bits[2]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC1_CODE4_CNT, pTable1->bits[3]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC1_CODE5_CNT, pTable1->bits[4]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC1_CODE6_CNT, pTable1->bits[5]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC1_CODE7_CNT, pTable1->bits[6]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC1_CODE8_CNT, pTable1->bits[7]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC1_CODE9_CNT, pTable1->bits[8]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC1_CODE10_CNT, pTable1->bits[9]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC1_CODE11_CNT, pTable1->bits[10]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC1_CODE12_CNT, pTable1->bits[11]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC1_CODE13_CNT, pTable1->bits[12]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC1_CODE14_CNT, pTable1->bits[13]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC1_CODE15_CNT, pTable1->bits[14]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC1_CODE16_CNT, pTable1->bits[15]);
|
|
return;
|
}
|
|
/*------------------------------------------------------------------------------
|
|
Function name: JpegDecWriteLenBitsProgressive
|
|
Functional description:
|
tell hw how many vlc words of different lengths we have
|
|
Inputs:
|
JpegDecContainer *pJpegDecCont
|
|
Outputs:
|
void
|
|
------------------------------------------------------------------------------*/
|
static void JpegDecWriteLenBitsProgressive(JpegDecContainer * pJpegDecCont)
|
{
|
|
RK_U32 i;
|
|
JpegDecContainer *PTR_JPGC = pJpegDecCont;
|
ScanInfo *JPG_SCN = &pJpegDecCont->scan;
|
HuffmanTables *JPG_VLC = &pJpegDecCont->vlc;
|
QuantTables *JPG_QTB = &pJpegDecCont->quant;
|
FrameInfo *JPG_FRM = &pJpegDecCont->frame;
|
|
VlcTable *pTable1 = NULL;
|
VlcTable *pTable2 = NULL;
|
VlcTable *pTable3 = NULL;
|
VlcTable *pTable4 = NULL;
|
|
/* reset swregs that contains vlc length information: swregs [16-28] */
|
for (i = JPEGDEC_VLC_LEN_START_REG; i < JPEGDEC_VLC_LEN_END_REG; i++)
|
PTR_JPGC->jpegRegs[i] = 0;
|
|
/* check if interleaved scan ==> only one table needed */
|
if (PTR_JPGC->info.nonInterleaved) {
|
/* check if AC or DC coefficient scan */
|
if (PTR_JPGC->scan.Ss == 0) { /* DC */
|
/* check component ÍD */
|
if (PTR_JPGC->info.componentId == 0) {
|
if (JPG_SCN->Td[0] == 0)
|
pTable1 = &(JPG_VLC->dcTable0);
|
else if (JPG_SCN->Td[0] == 1)
|
pTable1 = &(JPG_VLC->dcTable1);
|
else if (JPG_SCN->Td[0] == 2)
|
pTable1 = &(JPG_VLC->dcTable2);
|
else
|
pTable1 = &(JPG_VLC->dcTable3);
|
} else if (PTR_JPGC->info.componentId == 1) {
|
if (JPG_SCN->Td[1] == 0)
|
pTable1 = &(JPG_VLC->dcTable0);
|
else if (JPG_SCN->Td[1] == 1)
|
pTable1 = &(JPG_VLC->dcTable1);
|
else if (JPG_SCN->Td[1] == 2)
|
pTable1 = &(JPG_VLC->dcTable2);
|
else
|
pTable1 = &(JPG_VLC->dcTable3);
|
} else {
|
if (JPG_SCN->Td[2] == 0)
|
pTable1 = &(JPG_VLC->dcTable0);
|
else if (JPG_SCN->Td[2] == 1)
|
pTable1 = &(JPG_VLC->dcTable1);
|
else if (JPG_SCN->Td[2] == 2)
|
pTable1 = &(JPG_VLC->dcTable2);
|
else
|
pTable1 = &(JPG_VLC->dcTable3);
|
}
|
|
ASSERT(pTable1);
|
|
/* if later stage DC ==> no need for table */
|
if (PTR_JPGC->scan.Ah == 0) {
|
/* write DC table 1 */
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC1_CODE1_CNT,
|
pTable1->bits[0]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC1_CODE2_CNT,
|
pTable1->bits[1]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC1_CODE3_CNT,
|
pTable1->bits[2]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC1_CODE4_CNT,
|
pTable1->bits[3]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC1_CODE5_CNT,
|
pTable1->bits[4]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC1_CODE6_CNT,
|
pTable1->bits[5]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC1_CODE7_CNT,
|
pTable1->bits[6]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC1_CODE8_CNT,
|
pTable1->bits[7]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC1_CODE9_CNT,
|
pTable1->bits[8]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC1_CODE10_CNT,
|
pTable1->bits[9]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC1_CODE11_CNT,
|
pTable1->bits[10]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC1_CODE12_CNT,
|
pTable1->bits[11]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC1_CODE13_CNT,
|
pTable1->bits[12]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC1_CODE14_CNT,
|
pTable1->bits[13]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC1_CODE15_CNT,
|
pTable1->bits[14]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC1_CODE16_CNT,
|
pTable1->bits[15]);
|
} else {
|
/* write zero table */
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC1_CODE1_CNT, 0);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC1_CODE2_CNT, 0);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC1_CODE3_CNT, 0);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC1_CODE4_CNT, 0);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC1_CODE5_CNT, 0);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC1_CODE6_CNT, 0);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC1_CODE7_CNT, 0);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC1_CODE8_CNT, 0);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC1_CODE9_CNT, 0);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC1_CODE10_CNT, 0);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC1_CODE11_CNT, 0);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC1_CODE12_CNT, 0);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC1_CODE13_CNT, 0);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC1_CODE14_CNT, 0);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC1_CODE15_CNT, 0);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC1_CODE16_CNT, 0);
|
}
|
|
} else { /* AC */
|
/* check component ÍD */
|
if (PTR_JPGC->info.componentId == 0) {
|
if (JPG_SCN->Ta[0] == 0)
|
pTable1 = &(JPG_VLC->acTable0);
|
else if (JPG_SCN->Ta[0] == 1)
|
pTable1 = &(JPG_VLC->acTable1);
|
else if (JPG_SCN->Ta[0] == 2)
|
pTable1 = &(JPG_VLC->acTable2);
|
else
|
pTable1 = &(JPG_VLC->acTable3);
|
} else if (PTR_JPGC->info.componentId == 1) {
|
if (JPG_SCN->Ta[1] == 0)
|
pTable1 = &(JPG_VLC->acTable0);
|
else if (JPG_SCN->Ta[1] == 1)
|
pTable1 = &(JPG_VLC->acTable1);
|
else if (JPG_SCN->Ta[1] == 2)
|
pTable1 = &(JPG_VLC->acTable2);
|
else
|
pTable1 = &(JPG_VLC->acTable3);
|
} else {
|
if (JPG_SCN->Ta[2] == 0)
|
pTable1 = &(JPG_VLC->acTable0);
|
else if (JPG_SCN->Ta[2] == 1)
|
pTable1 = &(JPG_VLC->acTable1);
|
else if (JPG_SCN->Ta[2] == 2)
|
pTable1 = &(JPG_VLC->acTable2);
|
else
|
pTable1 = &(JPG_VLC->acTable3);
|
}
|
|
ASSERT(pTable1);
|
|
/* write AC table 1 */
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_AC1_CODE1_CNT,
|
pTable1->bits[0]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_AC1_CODE2_CNT,
|
pTable1->bits[1]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_AC1_CODE3_CNT,
|
pTable1->bits[2]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_AC1_CODE4_CNT,
|
pTable1->bits[3]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_AC1_CODE5_CNT,
|
pTable1->bits[4]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_AC1_CODE6_CNT,
|
pTable1->bits[5]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_AC1_CODE7_CNT,
|
pTable1->bits[6]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_AC1_CODE8_CNT,
|
pTable1->bits[7]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_AC1_CODE9_CNT,
|
pTable1->bits[8]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_AC1_CODE10_CNT,
|
pTable1->bits[9]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_AC1_CODE11_CNT,
|
pTable1->bits[10]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_AC1_CODE12_CNT,
|
pTable1->bits[11]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_AC1_CODE13_CNT,
|
pTable1->bits[12]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_AC1_CODE14_CNT,
|
pTable1->bits[13]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_AC1_CODE15_CNT,
|
pTable1->bits[14]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_AC1_CODE16_CNT,
|
pTable1->bits[15]);
|
}
|
} else { /* interleaved */
|
/* first select the table we'll use */
|
/* this trick is done because hw always wants luma table as ac hw table 1 */
|
|
if (JPG_SCN->Td[0] == 0)
|
pTable1 = &(JPG_VLC->dcTable0);
|
else if (JPG_SCN->Td[0] == 1)
|
pTable1 = &(JPG_VLC->dcTable1);
|
else if (JPG_SCN->Td[0] == 2)
|
pTable1 = &(JPG_VLC->dcTable2);
|
else
|
pTable1 = &(JPG_VLC->dcTable3);
|
|
if (JPG_SCN->Td[1] == 0)
|
pTable2 = &(JPG_VLC->dcTable0);
|
else if (JPG_SCN->Td[1] == 1)
|
pTable2 = &(JPG_VLC->dcTable1);
|
else if (JPG_SCN->Td[1] == 2)
|
pTable2 = &(JPG_VLC->dcTable2);
|
else
|
pTable2 = &(JPG_VLC->dcTable3);
|
|
if (JPG_SCN->Td[2] == 0)
|
pTable3 = &(JPG_VLC->dcTable0);
|
else if (JPG_SCN->Td[2] == 1)
|
pTable3 = &(JPG_VLC->dcTable1);
|
else if (JPG_SCN->Td[2] == 2)
|
pTable3 = &(JPG_VLC->dcTable2);
|
else
|
pTable3 = &(JPG_VLC->dcTable3);
|
|
ASSERT(pTable1);
|
ASSERT(pTable2);
|
ASSERT(pTable3);
|
|
/* if later stage DC ==> no need for table */
|
if (PTR_JPGC->scan.Ah == 0) {
|
/* write DC table 1 (luma) */
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC1_CODE1_CNT,
|
pTable1->bits[0]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC1_CODE2_CNT,
|
pTable1->bits[1]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC1_CODE3_CNT,
|
pTable1->bits[2]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC1_CODE4_CNT,
|
pTable1->bits[3]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC1_CODE5_CNT,
|
pTable1->bits[4]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC1_CODE6_CNT,
|
pTable1->bits[5]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC1_CODE7_CNT,
|
pTable1->bits[6]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC1_CODE8_CNT,
|
pTable1->bits[7]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC1_CODE9_CNT,
|
pTable1->bits[8]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC1_CODE10_CNT,
|
pTable1->bits[9]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC1_CODE11_CNT,
|
pTable1->bits[10]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC1_CODE12_CNT,
|
pTable1->bits[11]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC1_CODE13_CNT,
|
pTable1->bits[12]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC1_CODE14_CNT,
|
pTable1->bits[13]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC1_CODE15_CNT,
|
pTable1->bits[14]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC1_CODE16_CNT,
|
pTable1->bits[15]);
|
|
/* table DC2 (Cb) */
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC2_CODE1_CNT,
|
pTable2->bits[0]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC2_CODE2_CNT,
|
pTable2->bits[1]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC2_CODE3_CNT,
|
pTable2->bits[2]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC2_CODE4_CNT,
|
pTable2->bits[3]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC2_CODE5_CNT,
|
pTable2->bits[4]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC2_CODE6_CNT,
|
pTable2->bits[5]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC2_CODE7_CNT,
|
pTable2->bits[6]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC2_CODE8_CNT,
|
pTable2->bits[7]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC2_CODE9_CNT,
|
pTable2->bits[8]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC2_CODE10_CNT,
|
pTable2->bits[9]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC2_CODE11_CNT,
|
pTable2->bits[10]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC2_CODE12_CNT,
|
pTable2->bits[11]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC2_CODE13_CNT,
|
pTable2->bits[12]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC2_CODE14_CNT,
|
pTable2->bits[13]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC2_CODE15_CNT,
|
pTable2->bits[14]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC2_CODE16_CNT,
|
pTable2->bits[15]);
|
|
/* table DC2 (Cr) */
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC3_CODE1_CNT,
|
pTable3->bits[0]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC3_CODE2_CNT,
|
pTable3->bits[1]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC3_CODE3_CNT,
|
pTable3->bits[2]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC3_CODE4_CNT,
|
pTable3->bits[3]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC3_CODE5_CNT,
|
pTable3->bits[4]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC3_CODE6_CNT,
|
pTable3->bits[5]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC3_CODE7_CNT,
|
pTable3->bits[6]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC3_CODE8_CNT,
|
pTable3->bits[7]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC3_CODE9_CNT,
|
pTable3->bits[8]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC3_CODE10_CNT,
|
pTable3->bits[9]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC3_CODE11_CNT,
|
pTable3->bits[10]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC3_CODE12_CNT,
|
pTable3->bits[11]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC3_CODE13_CNT,
|
pTable3->bits[12]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC3_CODE14_CNT,
|
pTable3->bits[13]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC3_CODE15_CNT,
|
pTable3->bits[14]);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC3_CODE16_CNT,
|
pTable3->bits[15]);
|
} else {
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC1_CODE1_CNT, 0);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC1_CODE2_CNT, 0);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC1_CODE3_CNT, 0);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC1_CODE4_CNT, 0);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC1_CODE5_CNT, 0);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC1_CODE6_CNT, 0);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC1_CODE7_CNT, 0);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC1_CODE8_CNT, 0);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC1_CODE9_CNT, 0);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC1_CODE10_CNT, 0);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC1_CODE11_CNT, 0);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC1_CODE12_CNT, 0);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC1_CODE13_CNT, 0);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC1_CODE14_CNT, 0);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC1_CODE15_CNT, 0);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC1_CODE16_CNT, 0);
|
|
/* table DC2 (Cb) */
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC2_CODE1_CNT, 0);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC2_CODE2_CNT, 0);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC2_CODE3_CNT, 0);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC2_CODE4_CNT, 0);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC2_CODE5_CNT, 0);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC2_CODE6_CNT, 0);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC2_CODE7_CNT, 0);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC2_CODE8_CNT, 0);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC2_CODE9_CNT, 0);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC2_CODE10_CNT, 0);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC2_CODE11_CNT, 0);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC2_CODE12_CNT, 0);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC2_CODE13_CNT, 0);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC2_CODE14_CNT, 0);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC2_CODE15_CNT, 0);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC2_CODE16_CNT, 0);
|
|
/* table DC2 (Cr) */
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC3_CODE1_CNT, 0);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC3_CODE2_CNT, 0);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC3_CODE3_CNT, 0);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC3_CODE4_CNT, 0);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC3_CODE5_CNT, 0);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC3_CODE6_CNT, 0);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC3_CODE7_CNT, 0);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC3_CODE8_CNT, 0);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC3_CODE9_CNT, 0);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC3_CODE10_CNT, 0);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC3_CODE11_CNT, 0);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC3_CODE12_CNT, 0);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC3_CODE13_CNT, 0);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC3_CODE14_CNT, 0);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC3_CODE15_CNT, 0);
|
rk_SetRegisterFile(PTR_JPGC->reghandle, HWIF_DC3_CODE16_CNT, 0);
|
}
|
}
|
|
return;
|
}
|
|
/*------------------------------------------------------------------------------
|
|
Function name: JpegDecNextScanHdrs
|
|
Functional description:
|
Decodes next headers in case of non-interleaved stream
|
|
Inputs:
|
JpegDecContainer *pDecData Pointer to JpegDecContainer structure
|
|
Outputs:
|
OK/NOK
|
|
------------------------------------------------------------------------------*/
|
JpegDecRet JpegDecNextScanHdrs(JpegDecContainer * pJpegDecCont)
|
{
|
|
RK_U32 i;
|
RK_U32 currentByte = 0;
|
RK_U32 currentBytes = 0;
|
JpegDecRet retCode;
|
|
JpegDecContainer *PTR_JPGC = pJpegDecCont;
|
ScanInfo *JPG_SCN = &pJpegDecCont->scan;
|
HuffmanTables *JPG_VLC = &pJpegDecCont->vlc;
|
QuantTables *JPG_QTB = &pJpegDecCont->quant;
|
FrameInfo *JPG_FRM = &pJpegDecCont->frame;
|
|
retCode = JPEGDEC_OK;
|
|
/* reset for new headers */
|
PTR_JPGC->image.headerReady = 0;
|
|
/* find markers and go ! */
|
do {
|
/* Look for marker prefix byte from stream */
|
if (JpegDecGetByte(&(PTR_JPGC->stream)) == 0xFF) {
|
currentByte = JpegDecGetByte(&(PTR_JPGC->stream));
|
|
/* switch to certain header decoding */
|
switch (currentByte) {
|
case 0x00:
|
case SOF0:
|
case SOF2:
|
break;
|
/* Start of Scan */
|
case SOS:
|
/* reset image ready */
|
PTR_JPGC->image.imageReady = 0;
|
retCode = JpegDecDecodeScan(PTR_JPGC);
|
PTR_JPGC->image.headerReady = 1;
|
if (retCode != JPEGDEC_OK) {
|
if (retCode == JPEGDEC_STRM_ERROR) {
|
JPEGDEC_TRACE_INTERNAL(("JpegDecNextScanHdrs# ERROR: Stream error"));
|
return (retCode);
|
} else {
|
JPEGDEC_TRACE_INTERNAL(("JpegDecNextScanHdrs# JpegDecDecodeScan err\n"));
|
return (retCode);
|
}
|
}
|
|
if (PTR_JPGC->stream.bitPosInByte) {
|
/* delete stuffing bits */
|
currentByte = (8 - PTR_JPGC->stream.bitPosInByte);
|
if (JpegDecFlushBits
|
(&(PTR_JPGC->stream),
|
8 - PTR_JPGC->stream.bitPosInByte) == STRM_ERROR) {
|
JPEGDEC_TRACE_INTERNAL(("JpegDecNextScanHdrs# ERROR: Stream error"));
|
return (JPEGDEC_STRM_ERROR);
|
}
|
}
|
JPEGDEC_TRACE_INTERNAL(("JpegDecNextScanHdrs# Stuffing bits deleted\n"));
|
break;
|
/* Start of Huffman tables */
|
case DHT:
|
JPEGDEC_TRACE_INTERNAL(("JpegDecNextScanHdrs# JpegDecDecodeHuffmanTables dec"));
|
retCode = JpegDecDecodeHuffmanTables(PTR_JPGC);
|
JPEGDEC_TRACE_INTERNAL(("JpegDecNextScanHdrs# JpegDecDecodeHuffmanTables stops"));
|
if (retCode != JPEGDEC_OK) {
|
if (retCode == JPEGDEC_STRM_ERROR) {
|
JPEGDEC_TRACE_INTERNAL(("JpegDecNextScanHdrs# ERROR: Stream error"));
|
return (retCode);
|
} else {
|
JPEGDEC_TRACE_INTERNAL(("JpegDecNextScanHdrs# ERROR: JpegDecDecodeHuffmanTables err"));
|
return (retCode);
|
}
|
}
|
break;
|
/* start of Quantisation Tables */
|
case DQT:
|
JPEGDEC_TRACE_INTERNAL(("JpegDecNextScanHdrs# JpegDecDecodeQuantTables dec"));
|
retCode = JpegDecDecodeQuantTables(PTR_JPGC);
|
if (retCode != JPEGDEC_OK) {
|
if (retCode == JPEGDEC_STRM_ERROR) {
|
JPEGDEC_TRACE_INTERNAL(("JpegDecNextScanHdrs# ERROR: Stream error"));
|
return (retCode);
|
} else {
|
JPEGDEC_TRACE_INTERNAL(("JpegDecNextScanHdrs# ERROR: JpegDecDecodeQuantTables err"));
|
return (retCode);
|
}
|
}
|
break;
|
/* Start of Image */
|
case SOI:
|
/* no actions needed, continue */
|
break;
|
/* End of Image */
|
case EOI:
|
if (PTR_JPGC->image.imageReady) {
|
JPEGDEC_TRACE_INTERNAL(("JpegDecNextScanHdrs# EOI: OK\n"));
|
return (JPEGDEC_FRAME_READY);
|
} else {
|
JPEGDEC_TRACE_INTERNAL(("JpegDecNextScanHdrs# ERROR: EOI: NOK\n"));
|
return (JPEGDEC_ERROR);
|
}
|
/* Define Restart Interval */
|
case DRI:
|
JPEGDEC_TRACE_INTERNAL(("JpegDecNextScanHdrs# DRI"));
|
currentBytes = JpegDecGet2Bytes(&(PTR_JPGC->stream));
|
if (currentBytes == STRM_ERROR) {
|
JPEGDEC_TRACE_INTERNAL(("JpegDecNextScanHdrs# ERROR: Read bits "));
|
return (JPEGDEC_STRM_ERROR);
|
}
|
PTR_JPGC->frame.Ri = JpegDecGet2Bytes(&(PTR_JPGC->stream));
|
break;
|
/* Restart with modulo 8 count m */
|
case RST0:
|
case RST1:
|
case RST2:
|
case RST3:
|
case RST4:
|
case RST5:
|
case RST6:
|
case RST7:
|
/* initialisation of DC predictors to zero value !!! */
|
for (i = 0; i < MAX_NUMBER_OF_COMPONENTS; i++) {
|
PTR_JPGC->scan.pred[i] = 0;
|
}
|
JPEGDEC_TRACE_INTERNAL(("JpegDecNextScanHdrs# DC predictors init"));
|
break;
|
/* unsupported features */
|
case DNL:
|
case SOF1:
|
case SOF3:
|
case SOF5:
|
case SOF6:
|
case SOF7:
|
case SOF9:
|
case SOF10:
|
case SOF11:
|
case SOF13:
|
case SOF14:
|
case SOF15:
|
case DAC:
|
case DHP:
|
case TEM:
|
JPEGDEC_TRACE_INTERNAL(("JpegDecNextScanHdrs# ERROR: Unsupported Features"));
|
return (JPEGDEC_UNSUPPORTED);
|
/* application data & comments */
|
case APP0:
|
case APP1:
|
case APP2:
|
case APP3:
|
case APP4:
|
case APP5:
|
case APP6:
|
case APP7:
|
case APP8:
|
case APP9:
|
case APP10:
|
case APP11:
|
case APP12:
|
case APP13:
|
case APP14:
|
case APP15:
|
case COM:
|
JPEGDEC_TRACE_INTERNAL(("JpegDecNextScanHdrs# COM"));
|
currentBytes = JpegDecGet2Bytes(&(PTR_JPGC->stream));
|
if (currentBytes == STRM_ERROR) {
|
JPEGDEC_TRACE_INTERNAL(("JpegDecNextScanHdrs# ERROR: Read bits "));
|
return (JPEGDEC_STRM_ERROR);
|
}
|
/* jump over not supported header */
|
if (currentBytes != 0) {
|
PTR_JPGC->stream.readBits += ((currentBytes * 8) - 16);
|
PTR_JPGC->stream.pCurrPos +=
|
(((currentBytes * 8) - 16) / 8);
|
}
|
break;
|
default:
|
break;
|
}
|
} else {
|
if (currentByte == 0xFFFFFFFF) {
|
break;
|
}
|
}
|
|
if (PTR_JPGC->image.headerReady)
|
break;
|
} while ((PTR_JPGC->stream.readBits >> 3) <= PTR_JPGC->stream.streamLength);
|
|
return (JPEGDEC_OK);
|
}
|
|
/*------------------------------------------------------------------------------
|
Function name : JpegRefreshRegs
|
Description :
|
Return type : void
|
Argument : PPContainer * ppC
|
------------------------------------------------------------------------------*/
|
void JpegRefreshRegs(JpegDecContainer * pJpegDecCont)
|
{
|
return;
|
}
|
|
/*------------------------------------------------------------------------------
|
Function name : JpegFlushRegs
|
Description :
|
Return type : void
|
Argument : PPContainer * ppC
|
------------------------------------------------------------------------------*/
|
void JpegFlushRegs(JpegDecContainer * pJpegDecCont)
|
{
|
int i;
|
{/*
|
int i;
|
for (i = 0; i < 159; i++) {
|
printf("before reg[%d]=0x%08x \n", i, pJpegDecCont->jpegRegs[i]);
|
}*/
|
}
|
memcpy(pJpegDecCont->ioctl_info.regs, pJpegDecCont->jpegRegs, DEC_RK70_REGISTERS * sizeof(RK_U32));
|
|
RK_U32 *data = (RK_U32*) & (pJpegDecCont->ioctl_info);
|
/*for (i = 0; i < sizeof(pJpegDecCont->ioctl_info) / sizeof(RK_U32); i++ ) {
|
printf("reg[%03d]=0x%08x\n", i, data[i]);
|
|
}*/
|
|
if (VPUClientSendReg(pJpegDecCont->socket, (RK_U32*) & (pJpegDecCont->ioctl_info),
|
sizeof(pJpegDecCont->ioctl_info) / sizeof(RK_U32)))
|
ALOGV("JPEGFlushRegs fail\n");
|
else
|
ALOGV("JPEGFlushRegs success\n");
|
|
}
|
|
/*------------------------------------------------------------------------------
|
Function name : JpegDecInitHWEmptyScan
|
Description :
|
Return type : void
|
Argument :
|
------------------------------------------------------------------------------*/
|
static RK_U32 NumBits(RK_U32 value)
|
{
|
|
RK_U32 numBits = 0;
|
|
while (value) {
|
value >>= 1;
|
numBits++;
|
}
|
|
if (!numBits) {
|
numBits = 1;
|
}
|
|
return (numBits);
|
|
}
|
|
void JpegDecInitHWEmptyScan(JpegDecContainer * pJpegDecCont, RK_U32 componentId)
|
{
|
|
RK_U32 i;
|
RK_S32 n;
|
RK_U32 coeffBuffer = 0;
|
RK_U32 outputBuffer = 0;
|
RK_U32 numBlocks;
|
RK_U32 numMax;
|
RK_U8 *pStrm;
|
RK_U32 bits;
|
RK_U32 bitPos;
|
RK_U32 *pTableBase = NULL;
|
|
ASSERT(pJpegDecCont);
|
|
pJpegDecCont->info.nonInterleaved = 1;
|
pJpegDecCont->info.componentId = componentId;
|
|
if (pJpegDecCont->ppInstance == NULL && pJpegDecCont->info.userAllocMem == 1) {
|
/* if user allocated memory ==> new addresses */
|
pJpegDecCont->asicBuff.outLumaBuffer.vir_addr =
|
pJpegDecCont->info.givenOutLuma.vir_addr;
|
pJpegDecCont->asicBuff.outLumaBuffer.phy_addr =
|
pJpegDecCont->info.givenOutLuma.phy_addr;
|
pJpegDecCont->asicBuff.outChromaBuffer.vir_addr =
|
pJpegDecCont->info.givenOutChroma.vir_addr;
|
pJpegDecCont->asicBuff.outChromaBuffer.phy_addr =
|
pJpegDecCont->info.givenOutChroma.phy_addr;
|
pJpegDecCont->asicBuff.outChromaBuffer2.vir_addr =
|
pJpegDecCont->info.givenOutChroma2.vir_addr;
|
pJpegDecCont->asicBuff.outChromaBuffer2.phy_addr =
|
pJpegDecCont->info.givenOutChroma2.phy_addr;
|
}
|
|
/*************** Set swreg13 data ************/
|
/* Luminance output */
|
if (componentId == 0)
|
outputBuffer = pJpegDecCont->asicBuff.outLumaBuffer.phy_addr;
|
else if (componentId == 1)
|
outputBuffer = (pJpegDecCont->asicBuff.outChromaBuffer.phy_addr);
|
else
|
outputBuffer = (pJpegDecCont->asicBuff.outChromaBuffer2.phy_addr);
|
|
rk_SetRegisterFile(pJpegDecCont->jpegRegs, HWIF_DEC_OUT_BASE, outputBuffer);
|
|
pJpegDecCont->info.yCbCrMode = 0;
|
pJpegDecCont->info.X = pJpegDecCont->frame.hwX;
|
pJpegDecCont->info.Y = pJpegDecCont->frame.hwY;
|
pJpegDecCont->info.fillX = 0;
|
pJpegDecCont->info.fillY = 0;
|
numBlocks = pJpegDecCont->frame.hwX * pJpegDecCont->frame.hwY / 64;
|
coeffBuffer = pJpegDecCont->info.pCoeffBase.phy_addr;
|
if (componentId) {
|
coeffBuffer += JPEGDEC_COEFF_SIZE * numBlocks;
|
if (pJpegDecCont->info.yCbCrModeOrig == JPEGDEC_YUV420) {
|
pJpegDecCont->info.X /= 2;
|
if (pJpegDecCont->info.X & 0xF) {
|
pJpegDecCont->info.X += 8;
|
pJpegDecCont->info.fillX = 1;
|
}
|
pJpegDecCont->info.Y /= 2;
|
if (pJpegDecCont->info.Y & 0xF) {
|
pJpegDecCont->info.Y += 8;
|
pJpegDecCont->info.fillY = 1;
|
}
|
numBlocks /= 4;
|
} else if (pJpegDecCont->info.yCbCrModeOrig == JPEGDEC_YUV422) {
|
pJpegDecCont->info.X /= 2;
|
if (pJpegDecCont->info.X & 0xF) {
|
pJpegDecCont->info.X += 8;
|
pJpegDecCont->info.fillX = 1;
|
}
|
numBlocks /= 2;
|
} else if (pJpegDecCont->info.yCbCrModeOrig == JPEGDEC_YUV440) {
|
pJpegDecCont->info.Y /= 2;
|
if (pJpegDecCont->info.Y & 0xF) {
|
pJpegDecCont->info.Y += 8;
|
pJpegDecCont->info.fillY = 1;
|
}
|
numBlocks /= 2;
|
}
|
if (componentId > 1)
|
coeffBuffer += JPEGDEC_COEFF_SIZE * numBlocks;
|
}
|
|
pStrm = (RK_U8 *)pJpegDecCont->info.tmpStrm.vir_addr;
|
numMax = 0;
|
while (numBlocks > 32767) {
|
numBlocks -= 32767;
|
numMax++;
|
}
|
|
n = NumBits(numBlocks);
|
|
/* do we still have correct quantization tables ?? */
|
JPEGDEC_TRACE_INTERNAL(("INTERNAL: Write AC,DC,QP tables to base\n"));
|
JpegDecWriteTablesProgressive(pJpegDecCont);
|
|
/* two vlc codes, both with length 1 (can be done?), 0 for largest eob, 1
|
* for last eob (EOBn) */
|
/* write "length amounts" */
|
rk_SetRegisterFile(pJpegDecCont->jpegRegs, HWIF_AC1_CODE1_CNT, 2);
|
|
/* codeword values 0xE0 (for EOB run of 32767 blocks) and 0xn0 */
|
pTableBase = pJpegDecCont->frame.pTableBase.vir_addr;
|
pTableBase += 48; /* start of vlc tables */
|
*pTableBase = (0xE0 << 24) | ((n - 1) << 20);
|
|
/* write numMax ext eobs of length 32767 followed by last ext eob */
|
bitPos = 0;
|
for (i = 0; i < numMax; i++) {
|
bits = 0x3FFF << 17;
|
*pStrm = (bitPos ? *pStrm : 0) | bits >> (24 + bitPos);
|
pStrm++;
|
bits <<= 8 - bitPos;
|
*pStrm = bits >> 24;
|
if (bitPos >= 1) {
|
pStrm++;
|
bits <<= 8;
|
*pStrm = bits >> 24;
|
}
|
bitPos = (bitPos + 15) & 0x7;
|
}
|
|
if (numBlocks) {
|
/* codeword to be written:
|
* '1' to indicate EOBn followed by number of blocks - 2^(n-1) */
|
bits = numBlocks << (32 - n);
|
*pStrm = (bitPos ? *pStrm : 0) | bits >> (24 + bitPos);
|
pStrm++;
|
bits <<= 8 - bitPos;
|
n -= 8 - bitPos;
|
while (n > 0) {
|
*pStrm++ = bits >> 24;
|
bits <<= 8;
|
n -= 8;
|
}
|
}
|
|
rk_SetRegisterFile(pJpegDecCont->jpegRegs, HWIF_RLC_VLC_BASE,
|
pJpegDecCont->info.tmpStrm.phy_addr);
|
rk_SetRegisterFile(pJpegDecCont->jpegRegs, HWIF_STRM_START_BIT, 0);
|
rk_SetRegisterFile(pJpegDecCont->jpegRegs, HWIF_STREAM_LEN, 100);
|
|
JPEGDEC_TRACE_INTERNAL(("INTERNAL: Set input format\n"));
|
rk_SetRegisterFile(pJpegDecCont->jpegRegs, HWIF_JPEG_MODE, JPEGDEC_YUV400);
|
|
/* frame size, round up the number of mbs */
|
JPEGDEC_TRACE_INTERNAL(("INTERNAL: Set Frame width extension\n"));
|
rk_SetRegisterFile(pJpegDecCont->jpegRegs, HWIF_PIC_MB_W_EXT,
|
((((pJpegDecCont->info.X) >> (4)) & 0xE00) >> 9));
|
|
/* frame size, round up the number of mbs */
|
JPEGDEC_TRACE_INTERNAL(("INTERNAL: Set Frame width\n"));
|
rk_SetRegisterFile(pJpegDecCont->jpegRegs, HWIF_PIC_MB_WIDTH,
|
((pJpegDecCont->info.X) >> (4)) & 0x1FF);
|
|
/* frame size, round up the number of mbs */
|
JPEGDEC_TRACE_INTERNAL(("INTERNAL: Set Frame height extension\n"));
|
rk_SetRegisterFile(pJpegDecCont->jpegRegs, HWIF_PIC_MB_H_EXT,
|
((((pJpegDecCont->info.Y) >> (4)) & 0x700) >> 8));
|
|
/* frame size, round up the number of mbs */
|
JPEGDEC_TRACE_INTERNAL(("INTERNAL: Set Frame height\n"));
|
rk_SetRegisterFile(pJpegDecCont->jpegRegs, HWIF_PIC_MB_HEIGHT_P,
|
((pJpegDecCont->info.Y) >> (4)) & 0x0FF);
|
|
rk_SetRegisterFile(pJpegDecCont->jpegRegs, HWIF_PJPEG_WDIV8,
|
pJpegDecCont->info.fillX);
|
rk_SetRegisterFile(pJpegDecCont->jpegRegs, HWIF_JPEG_FILRIGHT_E,
|
pJpegDecCont->info.fillX);
|
rk_SetRegisterFile(pJpegDecCont->jpegRegs, HWIF_PJPEG_HDIV8,
|
pJpegDecCont->info.fillY);
|
rk_SetRegisterFile(pJpegDecCont->jpegRegs, HWIF_PJPEG_FILDOWN_E,
|
pJpegDecCont->info.fillY);
|
|
/*************** Set swreg52 data ************/
|
/* Set JPEG operation mode */
|
JPEGDEC_TRACE_INTERNAL(("INTERNAL: Set JPEG operation mode\n"));
|
rk_SetRegisterFile(pJpegDecCont->jpegRegs, HWIF_PJPEG_E, 1);
|
|
/* indicate first ac scan for any spectral coeffs, nothing will be changed
|
* as every block "skipped" by extended eobs */
|
rk_SetRegisterFile(pJpegDecCont->jpegRegs, HWIF_PJPEG_SS, 1);
|
rk_SetRegisterFile(pJpegDecCont->jpegRegs, HWIF_PJPEG_SE, 1);
|
rk_SetRegisterFile(pJpegDecCont->jpegRegs, HWIF_PJPEG_AH, 0);
|
rk_SetRegisterFile(pJpegDecCont->jpegRegs, HWIF_PJPEG_AL, 0);
|
|
JPEGDEC_TRACE_INTERNAL(("INTERNAL: Set coefficient buffer base address\n"));
|
rk_SetRegisterFile(pJpegDecCont->jpegRegs, HWIF_PJPEG_COEFF_BUF, coeffBuffer);
|
rk_SetRegisterFile(pJpegDecCont->jpegRegs, HWIF_DEC_OUT_DIS, 0);
|
|
/* write table base */
|
JPEGDEC_TRACE_INTERNAL(("INTERNAL: Set AC,DC,QP table base address\n"));
|
rk_SetRegisterFile(pJpegDecCont->jpegRegs, HWIF_QTABLE_BASE,
|
pJpegDecCont->frame.pTableBase.phy_addr);
|
|
rk_SetRegisterFile(pJpegDecCont->jpegRegs, HWIF_SYNC_MARKER_E, 0);
|
|
pJpegDecCont->asicRunning = 1;
|
|
/* Enable jpeg mode and set slice mode */
|
JPEGDEC_TRACE_INTERNAL(("INTERNAL: Enable jpeg\n"));
|
rk_SetRegisterFile(pJpegDecCont->jpegRegs, HWIF_DEC_E, 1);
|
/* Flush regs to hw register */
|
JpegFlushRegs(pJpegDecCont);
|
}
|
#ifdef DRM_LINUX
|
int SetPostProcessor(void *handle, MppBufferInfo *dst, int inWidth, int inHeigth,
|
int outWidth, int outHeight, int inColor, PostProcessInfo *ppInfo) //,int outColor,HW_BOOL dither)
|
#else
|
int SetPostProcessor(void *handle, VPUMemLinear_t *dst, int inWidth, int inHeigth,
|
int outWidth, int outHeight, int inColor, PostProcessInfo *ppInfo)
|
#endif
|
{
|
//modify following values in special product
|
#define BRIGHTNESS 0 // -128 ~ 127
|
#define CONTRAST 0 // -64 ~ 64
|
#define SATURATION 0 // -64 ~ 128
|
#define PP_IN_FORMAT_YUV422INTERLAVE 0
|
#define PP_IN_FORMAT_YUV420SEMI 1
|
#define PP_IN_FORMAT_YUV420PLANAR 2
|
#define PP_IN_FORMAT_YUV400 3
|
#define PP_IN_FORMAT_YUV422SEMI 4
|
#define PP_IN_FORMAT_YUV420SEMITIELED 5
|
#define PP_IN_FORMAT_YUV440SEMI 6
|
#define PP_IN_FORMAT_YUV444_SEMI 7
|
#define PP_IN_FORMAT_YUV411_SEMI 8
|
|
#define PP_OUT_FORMAT_RGB565 0
|
#define PP_OUT_FORMAT_ARGB 1
|
#define PP_OUT_FORMAT_YUV422INTERLAVE 3
|
#define PP_OUT_FORMAT_YUV420INTERLAVE 5
|
|
int outColor = ppInfo->outFomart;
|
int dither = ppInfo->shouldDither;
|
RK_U32 dstLum;
|
|
rk_SetRegisterFile(handle, HWIF_PP_AXI_RD_ID, 0);
|
rk_SetRegisterFile(handle, HWIF_PP_AXI_WR_ID, 0);
|
rk_SetRegisterFile(handle, HWIF_PP_AHB_HLOCK_E, 1);
|
rk_SetRegisterFile(handle, HWIF_PP_SCMD_DIS, 1);
|
rk_SetRegisterFile(handle, HWIF_PP_IN_A2_ENDSEL, 1);
|
rk_SetRegisterFile(handle, HWIF_PP_IN_A1_SWAP32, 1);
|
rk_SetRegisterFile(handle, HWIF_PP_IN_A1_ENDIAN, 1);
|
rk_SetRegisterFile(handle, HWIF_PP_IN_SWAP32_E, 1);
|
rk_SetRegisterFile(handle, HWIF_PP_DATA_DISC_E, 1);
|
rk_SetRegisterFile(handle, HWIF_PP_CLK_GATE_E, 1);
|
//rk_SetRegisterFile(handle, HWIF_PP_CLK_GATE_E, 0);
|
rk_SetRegisterFile(handle, HWIF_PP_IN_ENDIAN, 1);
|
rk_SetRegisterFile(handle, HWIF_PP_OUT_ENDIAN, 1);
|
rk_SetRegisterFile(handle, HWIF_PP_OUT_SWAP32_E, 1);
|
rk_SetRegisterFile(handle, HWIF_PP_MAX_BURST, 16);
|
|
rk_SetRegisterFile(handle, HWIF_PP_IN_LU_BASE, 0);
|
|
rk_SetRegisterFile(handle, HWIF_EXT_ORIG_WIDTH, inWidth >> 4);
|
|
if (ppInfo->cropW <= 0) {
|
rk_SetRegisterFile(handle, HWIF_PP_IN_W_EXT,
|
(((inWidth / 16) & 0xE00) >> 9));
|
rk_SetRegisterFile(handle, HWIF_PP_IN_WIDTH,
|
((inWidth / 16) & 0x1FF));
|
rk_SetRegisterFile(handle, HWIF_PP_IN_H_EXT,
|
(((inHeigth / 16) & 0x700) >> 8));
|
rk_SetRegisterFile(handle, HWIF_PP_IN_HEIGHT,
|
((inHeigth / 16) & 0x0FF));
|
} else {
|
rk_SetRegisterFile(handle, HWIF_PP_IN_W_EXT,
|
(((ppInfo->cropW / 16) & 0xE00) >> 9));
|
rk_SetRegisterFile(handle, HWIF_PP_IN_WIDTH,
|
((ppInfo->cropW / 16) & 0x1FF));
|
rk_SetRegisterFile(handle, HWIF_PP_IN_H_EXT,
|
(((ppInfo->cropH / 16) & 0x700) >> 8));
|
rk_SetRegisterFile(handle, HWIF_PP_IN_HEIGHT,
|
((ppInfo->cropH / 16) & 0x0FF));
|
rk_SetRegisterFile(handle, HWIF_CROP_STARTX_EXT,
|
(((ppInfo->cropX / 16) & 0xE00) >> 9));
|
rk_SetRegisterFile(handle, HWIF_CROP_STARTX,
|
((ppInfo->cropX / 16) & 0x1FF));
|
rk_SetRegisterFile(handle, HWIF_CROP_STARTY_EXT,
|
(((ppInfo->cropY / 16) & 0x700) >> 8));
|
rk_SetRegisterFile(handle, HWIF_CROP_STARTY,
|
((ppInfo->cropY / 16) & 0x0FF));
|
if (ppInfo->cropW & 0x0F) {
|
rk_SetRegisterFile(handle, HWIF_PP_CROP8_R_E, 1);
|
} else {
|
rk_SetRegisterFile(handle, HWIF_PP_CROP8_R_E, 0);
|
}
|
if (ppInfo->cropH & 0x0F) {
|
rk_SetRegisterFile(handle, HWIF_PP_CROP8_D_E, 1);
|
} else {
|
rk_SetRegisterFile(handle, HWIF_PP_CROP8_D_E, 0);
|
}
|
inWidth = ppInfo->cropW;
|
inHeigth = ppInfo->cropH;
|
}
|
|
rk_SetRegisterFile(handle, HWIF_DISPLAY_WIDTH, outWidth);
|
rk_SetRegisterFile(handle, HWIF_PP_OUT_WIDTH, outWidth);
|
rk_SetRegisterFile(handle, HWIF_PP_OUT_HEIGHT, outHeight);
|
rk_SetRegisterFile(handle, HWIF_PP_OUT_LU_BASE, dst->phy_addr);
|
|
switch (inColor) {
|
case PP_IN_FORMAT_YUV422INTERLAVE:
|
rk_SetRegisterFile(handle, HWIF_PP_IN_FORMAT, 0);
|
break;
|
case PP_IN_FORMAT_YUV420SEMI:
|
rk_SetRegisterFile(handle, HWIF_PP_IN_FORMAT, 1);
|
break;
|
case PP_IN_FORMAT_YUV420PLANAR:
|
rk_SetRegisterFile(handle, HWIF_PP_IN_FORMAT, 2);
|
break;
|
case PP_IN_FORMAT_YUV400:
|
rk_SetRegisterFile(handle, HWIF_PP_IN_FORMAT, 3);
|
break;
|
case PP_IN_FORMAT_YUV422SEMI:
|
rk_SetRegisterFile(handle, HWIF_PP_IN_FORMAT, 4);
|
break;
|
case PP_IN_FORMAT_YUV420SEMITIELED:
|
rk_SetRegisterFile(handle, HWIF_PP_IN_FORMAT, 5);
|
break;
|
case PP_IN_FORMAT_YUV440SEMI:
|
rk_SetRegisterFile(handle, HWIF_PP_IN_FORMAT, 6);
|
break;
|
case PP_IN_FORMAT_YUV444_SEMI:
|
rk_SetRegisterFile(handle, HWIF_PP_IN_FORMAT, 7);
|
rk_SetRegisterFile(handle, HWIF_PP_IN_FORMAT_ES, 0);
|
break;
|
case PP_IN_FORMAT_YUV411_SEMI:
|
rk_SetRegisterFile(handle, HWIF_PP_IN_FORMAT, 7);
|
rk_SetRegisterFile(handle, HWIF_PP_IN_FORMAT_ES, 1);
|
break;
|
default:
|
return -1;
|
}
|
#define VIDEORANGE 1 //0 or 1
|
int videoRange = VIDEORANGE;
|
rk_SetRegisterFile(handle, HWIF_RANGEMAP_COEF_Y, 9);
|
rk_SetRegisterFile(handle, HWIF_RANGEMAP_COEF_C, 9);
|
|
/* brightness */
|
rk_SetRegisterFile(handle, HWIF_COLOR_COEFFF, BRIGHTNESS);
|
|
if (outColor <= PP_OUT_FORMAT_ARGB) {
|
/*Bt.601*/
|
unsigned int a = 298;
|
unsigned int b = 409;
|
unsigned int c = 208;
|
unsigned int d = 100;
|
unsigned int e = 516;
|
|
/*Bt.709
|
unsigned int a = 298;
|
unsigned int b = 459;
|
unsigned int c = 137;
|
unsigned int d = 55;
|
unsigned int e = 544;*/
|
|
int satur = 0, tmp;
|
if (videoRange != 0) {
|
/*Bt.601*/
|
a = 256;
|
b = 350;
|
c = 179;
|
d = 86;
|
e = 443;
|
/*Bt.709
|
a = 256;
|
b = 403;
|
c = 120;
|
d = 48;
|
e = 475;*/
|
rk_SetRegisterFile(handle, HWIF_YCBCR_RANGE, videoRange);
|
}
|
int contrast = CONTRAST;
|
if (contrast != 0) {
|
int thr1y, thr2y, off1, off2, thr1, thr2, a1, a2;
|
if (videoRange == 0) {
|
int tmp1, tmp2;
|
/* Contrast */
|
thr1 = (219 * (contrast + 128)) / 512;
|
thr1y = (219 - 2 * thr1) / 2;
|
thr2 = 219 - thr1;
|
thr2y = 219 - thr1y;
|
|
tmp1 = (thr1y * 256) / thr1;
|
tmp2 = ((thr2y - thr1y) * 256) / (thr2 - thr1);
|
off1 = ((thr1y - ((tmp2 * thr1) / 256)) * a) / 256;
|
off2 = ((thr2y - ((tmp1 * thr2) / 256)) * a) / 256;
|
|
tmp1 = (64 * (contrast + 128)) / 128;
|
tmp2 = 256 * (128 - tmp1);
|
a1 = (tmp2 + off2) / thr1;
|
a2 = a1 + (256 * (off2 - 1)) / (thr2 - thr1);
|
} else {
|
/* Contrast */
|
thr1 = (64 * (contrast + 128)) / 128;
|
thr1y = 128 - thr1;
|
thr2 = 256 - thr1;
|
thr2y = 256 - thr1y;
|
a1 = (thr1y * 256) / thr1;
|
a2 = ((thr2y - thr1y) * 256) / (thr2 - thr1);
|
off1 = thr1y - (a2 * thr1) / 256;
|
off2 = thr2y - (a1 * thr2) / 256;
|
}
|
|
if (a1 > 1023)
|
a1 = 1023;
|
else if (a1 < 0)
|
a1 = 0;
|
|
if (a2 > 1023)
|
a2 = 1023;
|
else if (a2 < 0)
|
a2 = 0;
|
|
if (thr1 > 255)
|
thr1 = 255;
|
else if (thr1 < 0)
|
thr1 = 0;
|
|
if (thr2 > 255)
|
thr2 = 255;
|
else if (thr2 < 0)
|
thr2 = 0;
|
|
if (off1 > 511)
|
off1 = 511;
|
else if (off1 < -512)
|
off1 = -512;
|
|
if (off2 > 511)
|
off2 = 511;
|
else if (off2 < -512)
|
off2 = -512;
|
|
rk_SetRegisterFile(handle, HWIF_CONTRAST_THR1, thr1);
|
rk_SetRegisterFile(handle, HWIF_CONTRAST_THR2, thr2);
|
|
rk_SetRegisterFile(handle, HWIF_CONTRAST_OFF1, off1);
|
rk_SetRegisterFile(handle, HWIF_CONTRAST_OFF2, off2);
|
|
rk_SetRegisterFile(handle, HWIF_COLOR_COEFFA1, a1);
|
rk_SetRegisterFile(handle, HWIF_COLOR_COEFFA2, a2);
|
} else {
|
rk_SetRegisterFile(handle, HWIF_CONTRAST_THR1, 55);
|
rk_SetRegisterFile(handle, HWIF_CONTRAST_THR2, 165);
|
rk_SetRegisterFile(handle, HWIF_CONTRAST_OFF1, 0);
|
rk_SetRegisterFile(handle, HWIF_CONTRAST_OFF2, 0);
|
tmp = a;
|
if (tmp > 1023)
|
tmp = 1023;
|
else if (tmp < 0)
|
tmp = 0;
|
rk_SetRegisterFile(handle, HWIF_COLOR_COEFFA1, tmp);
|
rk_SetRegisterFile(handle, HWIF_COLOR_COEFFA2, tmp);
|
}
|
|
rk_SetRegisterFile(handle, HWIF_PP_OUT_ENDIAN, 0);
|
|
/* saturation */
|
satur = 64 + SATURATION;
|
|
tmp = (satur * (int) b) / 64;
|
if (tmp > 1023)
|
tmp = 1023;
|
else if (tmp < 0)
|
tmp = 0;
|
rk_SetRegisterFile(handle, HWIF_COLOR_COEFFB, (unsigned int) tmp);
|
|
tmp = (satur * (int) c) / 64;
|
if (tmp > 1023)
|
tmp = 1023;
|
else if (tmp < 0)
|
tmp = 0;
|
rk_SetRegisterFile(handle, HWIF_COLOR_COEFFC, (unsigned int) tmp);
|
|
tmp = (satur * (int) d) / 64;
|
if (tmp > 1023)
|
tmp = 1023;
|
else if (tmp < 0)
|
tmp = 0;
|
rk_SetRegisterFile(handle, HWIF_COLOR_COEFFD, (unsigned int) tmp);
|
|
tmp = (satur * (int) e) / 64;
|
if (tmp > 1023)
|
tmp = 1023;
|
else if (tmp < 0)
|
tmp = 0;
|
|
rk_SetRegisterFile(handle, HWIF_COLOR_COEFFE, (unsigned int) tmp);
|
}
|
|
switch (outColor) {
|
case PP_OUT_FORMAT_RGB565:
|
rk_SetRegisterFile(handle, HWIF_R_MASK, 0xF800F800);
|
rk_SetRegisterFile(handle, HWIF_G_MASK, 0x07E007E0);
|
rk_SetRegisterFile(handle, HWIF_B_MASK, 0x001F001F);
|
|
rk_SetRegisterFile(handle, HWIF_RGB_R_PADD, 0);
|
rk_SetRegisterFile(handle, HWIF_RGB_G_PADD, 5);
|
rk_SetRegisterFile(handle, HWIF_RGB_B_PADD, 11);
|
if (dither) { //always do dither
|
//WHLOG("we do dither.");
|
rk_SetRegisterFile(handle, HWIF_DITHER_SELECT_R, 2);
|
rk_SetRegisterFile(handle, HWIF_DITHER_SELECT_G, 3);
|
rk_SetRegisterFile(handle, HWIF_DITHER_SELECT_B, 2);
|
} else {
|
//WHLOG("we do not dither.");
|
}
|
rk_SetRegisterFile(handle, HWIF_RGB_PIX_IN32, 1);
|
rk_SetRegisterFile(handle, HWIF_PP_OUT_SWAP16_E, 1);
|
rk_SetRegisterFile(handle, HWIF_PP_OUT_FORMAT, 0);
|
break;
|
case PP_OUT_FORMAT_ARGB:
|
rk_SetRegisterFile(handle, HWIF_R_MASK, 0x000000FF | (0xff << 24));
|
rk_SetRegisterFile(handle, HWIF_G_MASK, 0x0000FF00 | (0xff << 24));
|
rk_SetRegisterFile(handle, HWIF_B_MASK, 0x00FF0000 | (0xff << 24));
|
rk_SetRegisterFile(handle, HWIF_RGB_R_PADD, 24);
|
rk_SetRegisterFile(handle, HWIF_RGB_G_PADD, 16);
|
rk_SetRegisterFile(handle, HWIF_RGB_B_PADD, 8);
|
|
rk_SetRegisterFile(handle, HWIF_RGB_PIX_IN32, 0);
|
rk_SetRegisterFile(handle, HWIF_PP_OUT_FORMAT, 0);
|
break;
|
case PP_OUT_FORMAT_YUV422INTERLAVE:
|
rk_SetRegisterFile(handle, HWIF_PP_OUT_FORMAT, 3);
|
break;
|
case PP_OUT_FORMAT_YUV420INTERLAVE: {
|
RK_U32 phy_addr = phy_addr = dst->phy_addr;
|
#if 0
|
if (!VPUMemJudgeIommu()) {
|
rk_SetRegisterFile(handle, HWIF_PP_OUT_CH_BASE, (phy_addr + outWidth * outHeight));
|
} else {
|
rk_SetRegisterFile(handle, HWIF_PP_OUT_CH_BASE, phy_addr);
|
}
|
#else
|
dstLum = dst->phy_addr | ((outWidth*outHeight)<<10);
|
//rk_SetRegisterFile(handle, HWIF_PP_OUT_CH_BASE, dstLum);
|
rk_SetRegisterFile(handle, HWIF_PP_OUT_CH_BASE, phy_addr);
|
#endif
|
rk_SetRegisterFile(handle, HWIF_PP_OUT_FORMAT, 5);
|
}
|
break;
|
default:
|
return -1;
|
}
|
|
rk_SetRegisterFile(handle, HWIF_ROTATION_MODE, 0);
|
|
|
{
|
unsigned int inw, inh;
|
unsigned int outw, outh;
|
|
inw = inWidth - 1;
|
inh = inHeigth - 1;
|
outw = outWidth - 1;
|
outh = outHeight - 1;
|
|
|
if (inw < outw) {
|
rk_SetRegisterFile(handle, HWIF_HOR_SCALE_MODE, 1);
|
rk_SetRegisterFile(handle, HWIF_SCALE_WRATIO, (outw << 16) / inw);
|
rk_SetRegisterFile(handle, HWIF_WSCALE_INVRA, (inw << 16) / outw);
|
} else if (inw > outw) {
|
rk_SetRegisterFile(handle, HWIF_HOR_SCALE_MODE, 2);
|
rk_SetRegisterFile(handle, HWIF_WSCALE_INVRA, ((outw + 1) << 16) / (inw + 1));
|
} else
|
rk_SetRegisterFile(handle, HWIF_HOR_SCALE_MODE, 0);
|
|
if (inh < outh) {
|
rk_SetRegisterFile(handle, HWIF_VER_SCALE_MODE, 1);
|
rk_SetRegisterFile(handle, HWIF_SCALE_HRATIO, (outh << 16) / inh);
|
rk_SetRegisterFile(handle, HWIF_HSCALE_INVRA, (inh << 16) / outh);
|
} else if (inh > outh) {
|
rk_SetRegisterFile(handle, HWIF_VER_SCALE_MODE, 2);
|
rk_SetRegisterFile(handle, HWIF_HSCALE_INVRA, ((outh + 1) << 16) / (inh + 1) + 1);
|
} else
|
rk_SetRegisterFile(handle, HWIF_VER_SCALE_MODE, 0);
|
}
|
|
rk_SetRegisterFile(handle, HWIF_PP_PIPELINE_E, ppInfo->enable);
|
return 0;
|
}
|