CARPLAY版本整理

This commit is contained in:
2025-01-21 16:49:37 +08:00
commit f0fb64e4e6
26542 changed files with 13719676 additions and 0 deletions

View File

@ -0,0 +1,165 @@
/*------------------------------------------------------------------------------
-- --
-- This software is confidential and proprietary and may be used --
-- only as expressly authorized by a licensing agreement from --
-- --
-- Hantro Products Oy. --
-- --
-- (C) COPYRIGHT 2006 HANTRO PRODUCTS OY --
-- ALL RIGHTS RESERVED --
-- --
-- The entire notice above must be reproduced --
-- on all copies and should not be removed. --
-- --
--------------------------------------------------------------------------------
--
-- Abstract : Stream decoding utilities
--
--------------------------------------------------------------------------------
--
-- Version control information, please leave untouched.
--
-- $RCSfile: bqueue.c,v $
-- $Date: 2010/07/23 09:19:10 $
-- $Revision: 1.4 $
--
------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------
Table of context
1. Include headers
2. External identifiers
3. Module defines
4. Module identifiers
5. Fuctions
------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------
1. Include headers
------------------------------------------------------------------------------*/
#include "bqueue.h"
#include "dwl.h"
#ifndef HANTRO_OK
#define HANTRO_OK (0)
#endif /* HANTRO_TRUE */
#ifndef HANTRO_NOK
#define HANTRO_NOK (1)
#endif /* HANTRO_FALSE*/
/*------------------------------------------------------------------------------
2. External identifiers
------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------
3. Module defines
------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------
4. Module indentifiers
------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------
BqueueInit
Initialize buffer queue
------------------------------------------------------------------------------*/
u32 BqueueInit( bufferQueue_t *bq, u32 numBuffers )
{
u32 i;
if( numBuffers == 0 )
return HANTRO_OK;
bq->picI = (u32*)DWLmalloc( sizeof(u32)*numBuffers);
if( bq->picI == NULL )
{
return HANTRO_NOK;
}
for( i = 0 ; i < numBuffers ; ++i )
{
bq->picI[i] = 0;
}
bq->queueSize = numBuffers;
bq->ctr = 1;
return HANTRO_OK;
}
/*------------------------------------------------------------------------------
BqueueRelease
------------------------------------------------------------------------------*/
void BqueueRelease( bufferQueue_t *bq )
{
if(bq->picI)
{
DWLfree(bq->picI);
bq->picI = NULL;
}
bq->prevAnchorSlot = 0;
bq->queueSize = 0;
}
/*------------------------------------------------------------------------------
BqueueNext
Return "oldest" available buffer.
------------------------------------------------------------------------------*/
u32 BqueueNext( bufferQueue_t *bq, u32 ref0, u32 ref1, u32 ref2, u32 bPic )
{
u32 minPicI = 1<<30;
u32 nextOut = (u32)0xFFFFFFFFU;
u32 i;
/* Find available buffer with smallest index number */
i = 0;
while( i < bq->queueSize )
{
if(i == ref0 || i == ref1 || i == ref2) /* Skip reserved anchor pictures */
{
i++;
continue;
}
if( bq->picI[i] < minPicI )
{
minPicI = bq->picI[i];
nextOut = i;
}
i++;
}
if( nextOut == (u32)0xFFFFFFFFU)
{
return 0; /* No buffers available, shouldn't happen */
}
/* Update queue state */
if( bPic )
{
bq->picI[nextOut] = bq->ctr-1;
bq->picI[bq->prevAnchorSlot]++;
}
else
{
bq->picI[nextOut] = bq->ctr;
}
bq->ctr++;
if( !bPic )
{
bq->prevAnchorSlot = nextOut;
}
return nextOut;
}
/*------------------------------------------------------------------------------
BqueueDiscard
"Discard" output buffer, e.g. if error concealment used and buffer
at issue is never going out.
------------------------------------------------------------------------------*/
void BqueueDiscard( bufferQueue_t *bq, u32 buffer )
{
bq->picI[buffer] = 0;
}

View File

@ -0,0 +1,941 @@
#include "FreeRTOS.h"
#include "chip.h"
#include "basetype.h"
#include "dwl_defs.h"
#include "dwl_freertos.h"
#include "dwl.h"
#include "hx170dec.h"
#define DWL_USE_DEC_IRQ
#define DWL_PJPEG_E 22 /* 1 bit */
#define DWL_REF_BUFF_E 20 /* 1 bit */
#define DWL_JPEG_EXT_E 31 /* 1 bit */
#define DWL_REF_BUFF_ILACE_E 30 /* 1 bit */
#define DWL_MPEG4_CUSTOM_E 29 /* 1 bit */
#define DWL_REF_BUFF_DOUBLE_E 28 /* 1 bit */
#define DWL_MVC_E 20 /* 2 bits */
#define DWL_DEC_TILED_L 17 /* 2 bits */
#define DWL_DEC_PIC_W_EXT 14 /* 2 bits */
#define DWL_EC_E 12 /* 2 bits */
#define DWL_STRIDE_E 11 /* 1 bit */
#define DWL_FIELD_DPB_E 10 /* 1 bit */
#define DWL_CFG_E 24 /* 4 bits */
#define DWL_PP_IN_TILED_L 14 /* 2 bits */
#define DWL_SORENSONSPARK_E 11 /* 1 bit */
#define DWL_H264_FUSE_E 31 /* 1 bit */
#define DWL_MPEG4_FUSE_E 30 /* 1 bit */
#define DWL_MPEG2_FUSE_E 29 /* 1 bit */
#define DWL_SORENSONSPARK_FUSE_E 28 /* 1 bit */
#define DWL_JPEG_FUSE_E 27 /* 1 bit */
#define DWL_VP6_FUSE_E 26 /* 1 bit */
#define DWL_VC1_FUSE_E 25 /* 1 bit */
#define DWL_PJPEG_FUSE_E 24 /* 1 bit */
#define DWL_CUSTOM_MPEG4_FUSE_E 23 /* 1 bit */
#define DWL_RV_FUSE_E 22 /* 1 bit */
#define DWL_VP7_FUSE_E 21 /* 1 bit */
#define DWL_VP8_FUSE_E 20 /* 1 bit */
#define DWL_AVS_FUSE_E 19 /* 1 bit */
#define DWL_MVC_FUSE_E 18 /* 1 bit */
#define DWL_DEC_MAX_1920_FUSE_E 15 /* 1 bit */
#define DWL_DEC_MAX_1280_FUSE_E 14 /* 1 bit */
#define DWL_DEC_MAX_720_FUSE_E 13 /* 1 bit */
#define DWL_DEC_MAX_352_FUSE_E 12 /* 1 bit */
#define DWL_REF_BUFF_FUSE_E 7 /* 1 bit */
#define DWL_PP_FUSE_E 31 /* 1 bit */
#define DWL_PP_DEINTERLACE_FUSE_E 30 /* 1 bit */
#define DWL_PP_ALPHA_BLEND_FUSE_E 29 /* 1 bit */
#define DWL_PP_MAX_4096_FUSE_E 16 /* 1 bit */
#define DWL_PP_MAX_1920_FUSE_E 15 /* 1 bit */
#define DWL_PP_MAX_1280_FUSE_E 14 /* 1 bit */
#define DWL_PP_MAX_720_FUSE_E 13 /* 1 bit */
#define DWL_PP_MAX_352_FUSE_E 12 /* 1 bit */
#define IS_PIPELINE_ENABLED(val) ((val) & 0x02)
/* shadow HW registers */
u32 dwlShadowRegs[MAX_ASIC_CORES][128];
#ifdef _DWL_DEBUG
static void PrintIrqType(u32 isPP, /*u32 coreID,*/ u32 status)
{
u32 coreID = 0;
if(isPP)
{
printf("PP[%d] IRQ %s\n", coreID,
status & PP_IRQ_RDY ? "READY" : "BUS ERROR");
}
else
{
if(status & DEC_IRQ_ABORT)
printf("DEC[%d] IRQ ABORT\n", coreID);
else if (status & DEC_IRQ_RDY)
printf("DEC[%d] IRQ READY\n", coreID);
else if (status & DEC_IRQ_BUS)
printf("DEC[%d] IRQ BUS ERROR\n", coreID);
else if (status & DEC_IRQ_BUFFER)
printf("DEC[%d] IRQ BUFFER\n", coreID);
else if (status & DEC_IRQ_ASO)
printf("DEC[%d] IRQ ASO\n", coreID);
else if (status & DEC_IRQ_ERROR)
printf("DEC[%d] IRQ STREAM ERROR\n", coreID);
else if (status & DEC_IRQ_SLICE)
printf("DEC[%d] IRQ SLICE\n", coreID);
else if (status & DEC_IRQ_TIMEOUT)
printf("DEC[%d] IRQ TIMEOUT\n", coreID);
else
printf("DEC[%d] IRQ UNKNOWN 0x%08x\n", coreID, status);
}
}
#endif
/*------------------------------------------------------------------------------
Function name : DWLReadAsicCoreCount
Description : Return the number of hardware cores available
------------------------------------------------------------------------------*/
u32 DWLReadAsicCoreCount(void)
{
unsigned int cores = 0;
/* ask module for cores */
if (vdec_ioctl(HX170DEC_IOC_MC_CORES, &cores) == -1)
{
DWL_DEBUG("ioctl failed\n");
cores = 0;
}
return (u32)cores;
}
/*------------------------------------------------------------------------------
Function name : DWLReadAsicID
Description : Read the HW ID. Does not need a DWL instance to run
Return type : u32 - the HW ID
------------------------------------------------------------------------------*/
u32 DWLReadAsicID()
{
u32 id = ~0;
unsigned long base;
DWL_DEBUG("\n");
/* ask module for base */
if(vdec_ioctl(HX170DEC_IOCGHWOFFSET, &base) == -1)
{
DWL_DEBUG("ioctl failed\n");
return id;
}
id = *(volatile unsigned int*)base;
return id;
}
static void ReadCoreFuse(const u32 *io, DWLHwFuseStatus_t *pHwFuseSts)
{
u32 configReg, fuseReg, fuseRegPp;
/* Decoder configuration */
configReg = io[HX170DEC_SYNTH_CFG];
/* Decoder fuse configuration */
fuseReg = io[HX170DEC_FUSE_CFG];
pHwFuseSts->h264SupportFuse = (fuseReg >> DWL_H264_FUSE_E) & 0x01U;
pHwFuseSts->mpeg4SupportFuse = (fuseReg >> DWL_MPEG4_FUSE_E) & 0x01U;
pHwFuseSts->mpeg2SupportFuse = (fuseReg >> DWL_MPEG2_FUSE_E) & 0x01U;
pHwFuseSts->sorensonSparkSupportFuse =
(fuseReg >> DWL_SORENSONSPARK_FUSE_E) & 0x01U;
pHwFuseSts->jpegSupportFuse = (fuseReg >> DWL_JPEG_FUSE_E) & 0x01U;
pHwFuseSts->vp6SupportFuse = (fuseReg >> DWL_VP6_FUSE_E) & 0x01U;
pHwFuseSts->vc1SupportFuse = (fuseReg >> DWL_VC1_FUSE_E) & 0x01U;
pHwFuseSts->jpegProgSupportFuse = (fuseReg >> DWL_PJPEG_FUSE_E) & 0x01U;
pHwFuseSts->rvSupportFuse = (fuseReg >> DWL_RV_FUSE_E) & 0x01U;
pHwFuseSts->avsSupportFuse = (fuseReg >> DWL_AVS_FUSE_E) & 0x01U;
pHwFuseSts->vp7SupportFuse = (fuseReg >> DWL_VP7_FUSE_E) & 0x01U;
pHwFuseSts->vp8SupportFuse = (fuseReg >> DWL_VP8_FUSE_E) & 0x01U;
pHwFuseSts->customMpeg4SupportFuse = (fuseReg >> DWL_CUSTOM_MPEG4_FUSE_E) & 0x01U;
pHwFuseSts->mvcSupportFuse = (fuseReg >> DWL_MVC_FUSE_E) & 0x01U;
/* check max. decoder output width */
if(fuseReg & 0x10000U)
pHwFuseSts->maxDecPicWidthFuse = 4096;
else if(fuseReg & 0x8000U)
pHwFuseSts->maxDecPicWidthFuse = 1920;
else if(fuseReg & 0x4000U)
pHwFuseSts->maxDecPicWidthFuse = 1280;
else if(fuseReg & 0x2000U)
pHwFuseSts->maxDecPicWidthFuse = 720;
else if(fuseReg & 0x1000U)
pHwFuseSts->maxDecPicWidthFuse = 352;
pHwFuseSts->refBufSupportFuse = (fuseReg >> DWL_REF_BUFF_FUSE_E) & 0x01U;
/* Pp configuration */
configReg = io[HX170PP_SYNTH_CFG];
if((configReg >> DWL_PP_E) & 0x01U)
{
/* Pp fuse configuration */
fuseRegPp = io[HX170PP_FUSE_CFG];
if((fuseRegPp >> DWL_PP_FUSE_E) & 0x01U)
{
pHwFuseSts->ppSupportFuse = 1;
/* check max. pp output width */
if(fuseRegPp & 0x10000U)
pHwFuseSts->maxPpOutPicWidthFuse = 4096;
else if(fuseRegPp & 0x8000U)
pHwFuseSts->maxPpOutPicWidthFuse = 1920;
else if(fuseRegPp & 0x4000U)
pHwFuseSts->maxPpOutPicWidthFuse = 1280;
else if(fuseRegPp & 0x2000U)
pHwFuseSts->maxPpOutPicWidthFuse = 720;
else if(fuseRegPp & 0x1000U)
pHwFuseSts->maxPpOutPicWidthFuse = 352;
pHwFuseSts->ppConfigFuse = fuseRegPp;
}
else
{
pHwFuseSts->ppSupportFuse = 0;
pHwFuseSts->maxPpOutPicWidthFuse = 0;
pHwFuseSts->ppConfigFuse = 0;
}
}
}
static void ReadCoreConfig(const u32 *io, DWLHwConfig_t *pHwCfg)
{
u32 configReg;
const u32 asicID = io[0];
/* Decoder configuration */
configReg = io[HX170DEC_SYNTH_CFG];
pHwCfg->h264Support = (configReg >> DWL_H264_E) & 0x3U;
/* check jpeg */
pHwCfg->jpegSupport = (configReg >> DWL_JPEG_E) & 0x01U;
if(pHwCfg->jpegSupport && ((configReg >> DWL_PJPEG_E) & 0x01U))
pHwCfg->jpegSupport = JPEG_PROGRESSIVE;
pHwCfg->mpeg4Support = (configReg >> DWL_MPEG4_E) & 0x3U;
pHwCfg->vc1Support = (configReg >> DWL_VC1_E) & 0x3U;
pHwCfg->mpeg2Support = (configReg >> DWL_MPEG2_E) & 0x01U;
pHwCfg->sorensonSparkSupport = (configReg >> DWL_SORENSONSPARK_E) & 0x01U;
#ifndef DWL_REFBUFFER_DISABLE
pHwCfg->refBufSupport = (configReg >> DWL_REF_BUFF_E) & 0x01U;
#else
pHwCfg->refBufSupport = 0;
#endif
pHwCfg->vp6Support = (configReg >> DWL_VP6_E) & 0x01U;
#ifdef DEC_X170_APF_DISABLE
if(DEC_X170_APF_DISABLE)
{
pHwCfg->tiledModeSupport = 0;
}
#endif /* DEC_X170_APF_DISABLE */
pHwCfg->maxDecPicWidth = configReg & 0x07FFU;
/* 2nd Config register */
configReg = io[HX170DEC_SYNTH_CFG_2];
if(pHwCfg->refBufSupport)
{
if((configReg >> DWL_REF_BUFF_ILACE_E) & 0x01U)
pHwCfg->refBufSupport |= 2;
if((configReg >> DWL_REF_BUFF_DOUBLE_E) & 0x01U)
pHwCfg->refBufSupport |= 4;
}
pHwCfg->customMpeg4Support = (configReg >> DWL_MPEG4_CUSTOM_E) & 0x01U;
pHwCfg->vp7Support = (configReg >> DWL_VP7_E) & 0x01U;
pHwCfg->vp8Support = (configReg >> DWL_VP8_E) & 0x01U;
pHwCfg->avsSupport = (configReg >> DWL_AVS_E) & 0x01U;
/* JPEG extensions */
if(((asicID >> 16) >= 0x8190U) || ((asicID >> 16) == 0x6731U))
pHwCfg->jpegESupport = (configReg >> DWL_JPEG_EXT_E) & 0x01U;
else
pHwCfg->jpegESupport = JPEG_EXT_NOT_SUPPORTED;
if(((asicID >> 16) >= 0x9170U) || ((asicID >> 16) == 0x6731U))
pHwCfg->rvSupport = (configReg >> DWL_RV_E) & 0x03U;
else
pHwCfg->rvSupport = RV_NOT_SUPPORTED;
pHwCfg->mvcSupport = (configReg >> DWL_MVC_E) & 0x03U;
pHwCfg->webpSupport = (configReg >> DWL_WEBP_E) & 0x01U;
pHwCfg->tiledModeSupport = (configReg >> DWL_DEC_TILED_L) & 0x03U;
pHwCfg->maxDecPicWidth += (( configReg >> DWL_DEC_PIC_W_EXT) & 0x03U ) << 11;
pHwCfg->ecSupport = (configReg >> DWL_EC_E) & 0x03U;
pHwCfg->strideSupport = (configReg >> DWL_STRIDE_E) & 0x01U;
pHwCfg->fieldDpbSupport = (configReg >> DWL_FIELD_DPB_E) & 0x01U;
if(pHwCfg->refBufSupport && ((asicID >> 16) == 0x6731U))
{
pHwCfg->refBufSupport |= 8; /* enable HW support for offset */
}
/* Pp configuration */
configReg = io[HX170PP_SYNTH_CFG];
if((configReg >> DWL_PP_E) & 0x01U)
{
pHwCfg->ppSupport = 1;
/* Theoretical max range 0...8191; actual 48...4096 */
pHwCfg->maxPpOutPicWidth = configReg & 0x1FFFU;
/*pHwCfg->ppConfig = (configReg >> DWL_CFG_E) & 0x0FU; */
pHwCfg->ppConfig = configReg;
}
else
{
pHwCfg->ppSupport = 0;
pHwCfg->maxPpOutPicWidth = 0;
pHwCfg->ppConfig = 0;
}
/* check the HW version */
if(((asicID >> 16) >= 0x8190U) || ((asicID >> 16) == 0x6731U))
{
u32 deInterlace;
u32 alphaBlend;
u32 deInterlaceFuse;
u32 alphaBlendFuse;
DWLHwFuseStatus_t hwFuseSts;
/* check fuse status */
ReadCoreFuse(io, &hwFuseSts);
/* Maximum decoding width supported by the HW */
if(pHwCfg->maxDecPicWidth > hwFuseSts.maxDecPicWidthFuse)
pHwCfg->maxDecPicWidth = hwFuseSts.maxDecPicWidthFuse;
/* Maximum output width of Post-Processor */
if(pHwCfg->maxPpOutPicWidth > hwFuseSts.maxPpOutPicWidthFuse)
pHwCfg->maxPpOutPicWidth = hwFuseSts.maxPpOutPicWidthFuse;
/* h264 */
if(!hwFuseSts.h264SupportFuse)
pHwCfg->h264Support = H264_NOT_SUPPORTED;
/* mpeg-4 */
if(!hwFuseSts.mpeg4SupportFuse)
pHwCfg->mpeg4Support = MPEG4_NOT_SUPPORTED;
/* custom mpeg-4 */
if(!hwFuseSts.customMpeg4SupportFuse)
pHwCfg->customMpeg4Support = MPEG4_CUSTOM_NOT_SUPPORTED;
/* jpeg (baseline && progressive) */
if(!hwFuseSts.jpegSupportFuse)
pHwCfg->jpegSupport = JPEG_NOT_SUPPORTED;
if((pHwCfg->jpegSupport == JPEG_PROGRESSIVE) &&
!hwFuseSts.jpegProgSupportFuse)
pHwCfg->jpegSupport = JPEG_BASELINE;
/* mpeg-2 */
if(!hwFuseSts.mpeg2SupportFuse)
pHwCfg->mpeg2Support = MPEG2_NOT_SUPPORTED;
/* vc-1 */
if(!hwFuseSts.vc1SupportFuse)
pHwCfg->vc1Support = VC1_NOT_SUPPORTED;
/* vp6 */
if(!hwFuseSts.vp6SupportFuse)
pHwCfg->vp6Support = VP6_NOT_SUPPORTED;
/* vp7 */
if(!hwFuseSts.vp7SupportFuse)
pHwCfg->vp7Support = VP7_NOT_SUPPORTED;
/* vp8 */
if(!hwFuseSts.vp8SupportFuse)
pHwCfg->vp8Support = VP8_NOT_SUPPORTED;
/* webp */
if(!hwFuseSts.vp8SupportFuse)
pHwCfg->webpSupport = WEBP_NOT_SUPPORTED;
/* pp */
if(!hwFuseSts.ppSupportFuse)
pHwCfg->ppSupport = PP_NOT_SUPPORTED;
/* check the pp config vs fuse status */
if((pHwCfg->ppConfig & 0xFC000000) &&
((hwFuseSts.ppConfigFuse & 0xF0000000) >> 5))
{
/* config */
deInterlace = ((pHwCfg->ppConfig & PP_DEINTERLACING) >> 25);
alphaBlend = ((pHwCfg->ppConfig & PP_ALPHA_BLENDING) >> 24);
/* fuse */
deInterlaceFuse =
(((hwFuseSts.ppConfigFuse >> 5) & PP_DEINTERLACING) >> 25);
alphaBlendFuse =
(((hwFuseSts.ppConfigFuse >> 5) & PP_ALPHA_BLENDING) >> 24);
/* check if */
if(deInterlace && !deInterlaceFuse)
pHwCfg->ppConfig &= 0xFD000000;
if(alphaBlend && !alphaBlendFuse)
pHwCfg->ppConfig &= 0xFE000000;
}
/* sorenson */
if(!hwFuseSts.sorensonSparkSupportFuse)
pHwCfg->sorensonSparkSupport = SORENSON_SPARK_NOT_SUPPORTED;
/* ref. picture buffer */
if(!hwFuseSts.refBufSupportFuse)
pHwCfg->refBufSupport = REF_BUF_NOT_SUPPORTED;
/* rv */
if(!hwFuseSts.rvSupportFuse)
pHwCfg->rvSupport = RV_NOT_SUPPORTED;
/* avs */
if(!hwFuseSts.avsSupportFuse)
pHwCfg->avsSupport = AVS_NOT_SUPPORTED;
/* mvc */
if(!hwFuseSts.mvcSupportFuse)
pHwCfg->mvcSupport = MVC_NOT_SUPPORTED;
}
}
/*------------------------------------------------------------------------------
Function name : DWLReadAsicConfig
Description : Read HW configuration. Does not need a DWL instance to run
Return type : DWLHwConfig_t - structure with HW configuration
------------------------------------------------------------------------------*/
void DWLReadAsicConfig(DWLHwConfig_t *pHwCfg)
{
unsigned long base;
DWL_DEBUG("\n");
/* ask module for base */
if(vdec_ioctl(HX170DEC_IOCGHWOFFSET, &base) == -1)
{
DWL_DEBUG("ioctl HX170DEC_IOCGHWOFFSET failed\n");
return;
}
/* Decoder configuration */
memset(pHwCfg, 0, sizeof(*pHwCfg));
ReadCoreConfig((const u32 *)base, pHwCfg);
}
void DWLReadMCAsicConfig(DWLHwConfig_t pHwCfg[MAX_ASIC_CORES])
{
unsigned int nCores, i;
unsigned long mcRegBase[MAX_ASIC_CORES];
DWL_DEBUG("\n");
if(vdec_ioctl(HX170DEC_IOC_MC_CORES, &nCores) == -1)
{
DWL_DEBUG("ioctl HX170DEC_IOC_MC_CORES failed\n");
return;
}
configASSERT(nCores <= MAX_ASIC_CORES);
if(vdec_ioctl(HX170DEC_IOC_MC_OFFSETS, mcRegBase) == -1)
{
DWL_DEBUG("ioctl HX170DEC_IOC_MC_OFFSETS failed\n");
return;
}
/* Decoder configuration */
memset(pHwCfg, 0, MAX_ASIC_CORES * sizeof(*pHwCfg));
for (i = 0; i < nCores; i++)
{
ReadCoreConfig((const u32 *)mcRegBase[i], pHwCfg + i);
}
}
/*------------------------------------------------------------------------------
Function name : DWLReadAsicFuseStatus
Description : Read HW fuse configuration. Does not need a DWL instance to run
Returns : DWLHwFuseStatus_t * pHwFuseSts - structure with HW fuse configuration
------------------------------------------------------------------------------*/
void DWLReadAsicFuseStatus(DWLHwFuseStatus_t * pHwFuseSts)
{
unsigned long base;
//unsigned int regSize;
DWL_DEBUG("\n");
memset(pHwFuseSts, 0, sizeof(*pHwFuseSts));
/* ask module for base */
if(vdec_ioctl(HX170DEC_IOCGHWOFFSET, &base) == -1)
{
DWL_DEBUG("ioctl failed\n");
return;
}
/* Decoder fuse configuration */
ReadCoreFuse((const u32*)base, pHwFuseSts);
}
/*------------------------------------------------------------------------------
Function name : DWLMallocRefFrm
Description : Allocate a frame buffer (contiguous linear RAM memory)
Return type : i32 - 0 for success or a negative error code
Argument : const void * instance - DWL instance
Argument : u32 size - size in bytes of the requested memory
Argument : void *info - place where the allocated memory buffer
parameters are returned
------------------------------------------------------------------------------*/
i32 DWLMallocRefFrm(const void *instance, u32 size, DWLLinearMem_t * info)
{
#ifdef MEMORY_USAGE_TRACE
printf("DWLMallocRefFrm\t%8d bytes\n", size);
#endif
return DWLMallocLinear(instance, size, info);
}
/*------------------------------------------------------------------------------
Function name : DWLFreeRefFrm
Description : Release a frame buffer previously allocated with
DWLMallocRefFrm.
Return type : void
Argument : const void * instance - DWL instance
Argument : void *info - frame buffer memory information
------------------------------------------------------------------------------*/
void DWLFreeRefFrm(const void *instance, DWLLinearMem_t * info)
{
DWLFreeLinear(instance, info);
}
/*------------------------------------------------------------------------------
Function name : DWLMallocLinear
Description : Allocate a contiguous, linear RAM memory buffer
Return type : i32 - 0 for success or a negative error code
Argument : const void * instance - DWL instance
Argument : u32 size - size in bytes of the requested memory
Argument : void *info - place where the allocated memory buffer
parameters are returned
------------------------------------------------------------------------------*/
i32 DWLMallocLinear(const void *instance, u32 size, DWLLinearMem_t * info)
{
hX170dwl_t *dec_dwl = (hX170dwl_t *) instance;
configASSERT(dec_dwl != NULL);
configASSERT(info != NULL);
#ifdef MEMORY_USAGE_TRACE
printf("DWLMallocLinear\t%8d bytes \n", size);
#endif
info->size = size;
info->virtualAddress = (u32 *)pvPortMalloc(size);
info->busAddress = (u32)info->virtualAddress;
info->virtualAddress = (u32 *)PHY_TO_UNCACHED_VIRT(info->virtualAddress);//info->virtualAddress + PHY_TO_VIR/4;
CP15_invalidate_dcache_for_dma(info->busAddress, info->busAddress + size);
#ifdef MEMORY_USAGE_TRACE
printf("DWLMallocLinear 0x%08x virtualAddress: 0x%08x\n",
info->busAddress, (unsigned) info->virtualAddress);
#endif
if(info->virtualAddress == NULL)
return DWL_ERROR;
return DWL_OK;
}
/*------------------------------------------------------------------------------
Function name : DWLFreeLinear
Description : Release a linera memory buffer, previously allocated with
DWLMallocLinear.
Return type : void
Argument : const void * instance - DWL instance
Argument : void *info - linear buffer memory information
------------------------------------------------------------------------------*/
void DWLFreeLinear(const void *instance, DWLLinearMem_t * info)
{
hX170dwl_t *dec_dwl = (hX170dwl_t *) instance;
configASSERT(dec_dwl != NULL);
configASSERT(info != NULL);
if(info->virtualAddress != NULL)
vPortFree((u32*)UNCACHED_VIRT_TO_PHT(info->virtualAddress));
}
/*------------------------------------------------------------------------------
Function name : DWLWriteReg
Description : Write a value to a hardware IO register
Return type : void
Argument : const void * instance - DWL instance
Argument : u32 offset - byte offset of the register to be written
Argument : u32 value - value to be written out
------------------------------------------------------------------------------*/
void DWLWriteReg(const void *instance, /*i32 coreID,*/ u32 offset, u32 value)
{
hX170dwl_t *dec_dwl = (hX170dwl_t *) instance;
i32 coreID = 0;
#ifndef DWL_DISABLE_REG_PRINTS
DWL_DEBUG("core[%d] swreg[%d] at offset 0x%02X = %08X\n",
coreID, offset/4, offset, value);
#endif
configASSERT((dec_dwl->clientType != DWL_CLIENT_TYPE_PP &&
offset < HX170PP_REG_START) ||
(dec_dwl->clientType == DWL_CLIENT_TYPE_PP &&
offset >= HX170PP_REG_START));
configASSERT(dec_dwl != NULL);
configASSERT(offset < dec_dwl->regSize);
configASSERT(coreID < (i32)dec_dwl->numCores);
offset = offset / 4;
dwlShadowRegs[coreID][offset] = value;
}
/*------------------------------------------------------------------------------
Function name : DWLReadReg
Description : Read the value of a hardware IO register
Return type : u32 - the value stored in the register
Argument : const void * instance - DWL instance
Argument : u32 offset - byte offset of the register to be read
------------------------------------------------------------------------------*/
u32 DWLReadReg(const void *instance, /*i32 coreID,*/ u32 offset)
{
hX170dwl_t *dec_dwl = (hX170dwl_t *) instance;
u32 val;
i32 coreID = 0;
configASSERT(dec_dwl != NULL);
configASSERT((dec_dwl->clientType != DWL_CLIENT_TYPE_PP &&
offset < HX170PP_REG_START) ||
(dec_dwl->clientType == DWL_CLIENT_TYPE_PP &&
offset >= HX170PP_REG_START) || (offset == 0) ||
(offset == HX170PP_SYNTH_CFG));
configASSERT(offset < dec_dwl->regSize);
configASSERT(coreID < (i32)dec_dwl->numCores);
offset = offset / 4;
val = dwlShadowRegs[coreID][offset];
#ifndef DWL_DISABLE_REG_PRINTS
DWL_DEBUG("core[%d] swreg[%d] at offset 0x%02X = %08X\n",
coreID, offset, offset * 4, val);
#endif
return val;
}
/*------------------------------------------------------------------------------
Function name : DWLEnableHW
Description : Enable hw by writing to register
Return type : void
Argument : const void * instance - DWL instance
Argument : u32 offset - byte offset of the register to be written
Argument : u32 value - value to be written out
------------------------------------------------------------------------------*/
void DWLEnableHW(const void *instance, /*i32 coreID,*/ u32 offset, u32 value)
{
hX170dwl_t *dec_dwl = (hX170dwl_t *) instance;
struct core_desc core;
int isPP, ioctl_req;
i32 coreID = 0;
configASSERT(dec_dwl);
isPP = dec_dwl->clientType == DWL_CLIENT_TYPE_PP ? 1 : 0;
ioctl_req = isPP ? HX170DEC_IOCS_PP_PUSH_REG : HX170DEC_IOCS_DEC_PUSH_REG;
//printf("isPP:%d\n", isPP);
DWLWriteReg(dec_dwl, /*coreID,*/ offset, value);
DWL_DEBUG("%s %d enabled by previous DWLWriteReg\n",
isPP ? "PP" : "DEC", coreID);
core.id = coreID;
core.regs = dwlShadowRegs[coreID];
core.regs += isPP ? 60 : 0;
core.size = isPP ? 41 * 4 : 60 * 4;
#if 0 //add for test.
int i;
for(i=core.size/4-1; i>=0; i--) {
printf("*(volatile unsigned int*)(0x71200000 + %d) = 0x%x;\n",
i * 4, dwlShadowRegs[coreID][i]);
}
#endif
if(vdec_ioctl(ioctl_req, &core))
{
DWL_DEBUG("ioctl HX170DEC_IOCS_*_PUSH_REG failed\n");
configASSERT(0);
}
}
/*------------------------------------------------------------------------------
Function name : DWLDisableHW
Description : Disable hw by writing to register
Return type : void
Argument : const void * instance - DWL instance
Argument : u32 offset - byte offset of the register to be written
Argument : u32 value - value to be written out
------------------------------------------------------------------------------*/
void DWLDisableHW(const void *instance, /*i32 coreID,*/ u32 offset, u32 value)
{
hX170dwl_t *dec_dwl = (hX170dwl_t *) instance;
struct core_desc core;
int isPP, ioctl_req;
i32 coreID = 0;
configASSERT(dec_dwl);
isPP = dec_dwl->clientType == DWL_CLIENT_TYPE_PP ? 1 : 0;
ioctl_req = isPP ? HX170DEC_IOCS_PP_PUSH_REG : HX170DEC_IOCS_DEC_PUSH_REG;
DWLWriteReg(dec_dwl, /*coreID,*/ offset, value);
DWL_DEBUG("%s %d disabled by previous DWLWriteReg\n",
isPP ? "PP" : "DEC", coreID);
core.id = coreID;
core.regs = dwlShadowRegs[coreID];
core.regs += isPP ? 60 : 0;
core.size = isPP ? 41 * 4 : 60 * 4;
if (vdec_ioctl(ioctl_req, &core))
{
DWL_DEBUG("ioctl HX170DEC_IOCS_*_PUSH_REG failed\n");
configASSERT(0);
}
}
/*------------------------------------------------------------------------------
Function name : DWLWaitHwReady
Description : Wait until hardware has stopped running.
Used for synchronizing software runs with the hardware.
The wait could succed, timeout, or fail with an error.
Return type : i32 - one of the values DWL_HW_WAIT_OK
DWL_HW_WAIT_TIMEOUT
DWL_HW_WAIT_ERROR
Argument : const void * instance - DWL instance
------------------------------------------------------------------------------*/
i32 DWLWaitHwReady(const void *instance, /*i32 coreID,*/ u32 timeout)
{
const hX170dwl_t *dec_dwl = (hX170dwl_t *) instance;
struct core_desc core;
int isPP, ioctl_req;
i32 ret = DWL_HW_WAIT_OK;
i32 coreID = 0;
UNUSED(timeout);
#ifndef DWL_USE_DEC_IRQ
int max_wait_time = 10000; /* 10s in ms */
#endif
configASSERT(dec_dwl);
isPP = dec_dwl->clientType == DWL_CLIENT_TYPE_PP ? 1 : 0;
DWL_DEBUG("%s %d\n", isPP ? "PP" : "DEC", coreID);
core.id = coreID;
core.regs = dwlShadowRegs[coreID];
core.regs += isPP ? 60 : 0;
core.size = isPP ? 41 * 4 : 60 * 4;
#ifdef DWL_USE_DEC_IRQ
if(isPP)
{
ioctl_req = HX170DEC_IOCX_PP_WAIT;
if (vdec_ioctl(ioctl_req, &core))
{
DWL_DEBUG("ioctl HX170DEC_IOCG_*_WAIT failed\n");
ret = DWL_HW_WAIT_ERROR;
}
}
else
{
ioctl_req = HX170DEC_IOCX_DEC_WAIT;
if (vdec_ioctl(ioctl_req, &core))
{
DWL_DEBUG("ioctl HX170DEC_IOCG_*_WAIT failed\n");
ret = DWL_HW_WAIT_ERROR;
}
}
#else /* Polling */
ret = DWL_HW_WAIT_TIMEOUT;
ioctl_req = isPP ? HX170DEC_IOCS_PP_PULL_REG : HX170DEC_IOCS_DEC_PULL_REG;
do
{
u32 irq_stats;
const unsigned int usec = 1000; /* 1 ms polling interval */
if (vdec_ioctl(ioctl_req, &core))
{
DWL_DEBUG("ioctl HX170DEC_IOCS_*_PULL_REG failed\n");
ret = DWL_HW_WAIT_ERROR;
break;
}
irq_stats = isPP ? dwlShadowRegs[coreID][HX170_IRQ_STAT_PP] :
dwlShadowRegs[coreID][HX170_IRQ_STAT_DEC];
irq_stats = (irq_stats >> 11) & 0xFF;
if(irq_stats != 0)
{
ret = DWL_HW_WAIT_OK;
break;
}
usleep(usec);
max_wait_time--;
}
while (max_wait_time > 0);
#endif
#ifdef _DWL_DEBUG
{
u32 irq_stats = isPP ? dwlShadowRegs[coreID][HX170_IRQ_STAT_PP] :
dwlShadowRegs[coreID][HX170_IRQ_STAT_DEC];
PrintIrqType(isPP, coreID, irq_stats);
}
#endif
DWL_DEBUG("%s %d done\n", isPP ? "PP" : "DEC", coreID);
return ret;
}
/*------------------------------------------------------------------------------
Function name : DWLmalloc
Description : Allocate a memory block. Same functionality as
the ANSI C malloc()
Return type : void pointer to the allocated space, or NULL if there
is insufficient memory available
Argument : u32 n - Bytes to allocate
------------------------------------------------------------------------------*/
void *DWLmalloc(u32 n)
{
#ifdef MEMORY_USAGE_TRACE
printf("DWLmalloc\t%8d bytes\n", n);
#endif
return pvPortMalloc((size_t) n);
}
/*------------------------------------------------------------------------------
Function name : DWLfree
Description : Deallocates or frees a memory block. Same functionality as
the ANSI C free()
Return type : void
Argument : void *p - Previously allocated memory block to be freed
------------------------------------------------------------------------------*/
void DWLfree(void *p)
{
if(p != NULL)
vPortFree(p);
}
/*------------------------------------------------------------------------------
Function name : DWLcalloc
Description : Allocates an array in memory with elements initialized
to 0. Same functionality as the ANSI C calloc()
Return type : void pointer to the allocated space, or NULL if there
is insufficient memory available
}
Argument : u32 n - Number of elements
Argument : u32 s - Length in bytes of each element.
------------------------------------------------------------------------------*/
void *DWLcalloc(u32 n, u32 s)
{
#ifdef MEMORY_USAGE_TRACE
printf("DWLcalloc\t%8d bytes\n", n * s);
#endif
void *p = pvPortMalloc(n * s);
if (p) memset(p, 0, n * s);
return p;
}
/*------------------------------------------------------------------------------
Function name : DWLmemcpy
Description : Copies characters between buffers. Same functionality as
the ANSI C memcpy()
Return type : The value of destination d
Argument : void *d - Destination buffer
Argument : const void *s - Buffer to copy from
Argument : u32 n - Number of bytes to copy
------------------------------------------------------------------------------*/
void *DWLmemcpy(void *d, const void *s, u32 n)
{
return memcpy(d, s, (size_t) n);
}
/*------------------------------------------------------------------------------
Function name : DWLmemset
Description : Sets buffers to a specified character. Same functionality
as the ANSI C memset()
Return type : The value of destination d
Argument : void *d - Pointer to destination
Argument : i32 c - Character to set
Argument : u32 n - Number of characters
------------------------------------------------------------------------------*/
void *DWLmemset(void *d, i32 c, u32 n)
{
return memset(d, (int) c, (size_t) n);
}
/*------------------------------------------------------------------------------
Function name : DWLSoftResetAsic
Description : Soft reset hx170dec
Return type : none
------------------------------------------------------------------------------*/
void DWLSoftResetAsic(void)
{
sys_soft_reset(softreset_jpeg);
}

View File

@ -0,0 +1,257 @@
#include <string.h>
#include "FreeRTOS.h"
#include "basetype.h"
#include "dwl_freertos.h"
#include "dwl.h"
#include "hx170dec.h"
/*------------------------------------------------------------------------------
Function name : DWLInit
Description : Initialize a DWL instance
Return type : const void * - pointer to a DWL instance
Argument : void * param - not in use, application passes NULL
------------------------------------------------------------------------------*/
const void *DWLInit(DWLInitParam_t * param)
{
hX170dwl_t *dec_dwl;
dec_dwl = (hX170dwl_t *) pvPortMalloc(sizeof(hX170dwl_t));
memset(dec_dwl, 0, sizeof(hX170dwl_t));
DWL_DEBUG("INITIALIZE\n");
if(dec_dwl == NULL)
{
DWL_DEBUG("failed to alloc hX170dwl_t struct\n");
return NULL;
}
dec_dwl->clientType = param->clientType;
switch (dec_dwl->clientType)
{
case DWL_CLIENT_TYPE_H264_DEC:
case DWL_CLIENT_TYPE_MPEG4_DEC:
case DWL_CLIENT_TYPE_JPEG_DEC:
case DWL_CLIENT_TYPE_VC1_DEC:
case DWL_CLIENT_TYPE_MPEG2_DEC:
case DWL_CLIENT_TYPE_VP6_DEC:
case DWL_CLIENT_TYPE_VP8_DEC:
case DWL_CLIENT_TYPE_RV_DEC:
case DWL_CLIENT_TYPE_AVS_DEC:
case DWL_CLIENT_TYPE_PP:
{
break;
}
default:
{
DWL_DEBUG("Unknown client type no. %d\n", dec_dwl->clientType);
goto err;
}
}
if(vdec_ioctl(HX170DEC_IOC_MC_CORES, &dec_dwl->numCores) == -1)
{
DWL_DEBUG("ioctl HX170DEC_IOC_MC_CORES failed\n");
goto err;
}
if(vdec_ioctl(HX170DEC_IOCGHWIOSIZE, &dec_dwl->regSize) == -1)
{
DWL_DEBUG("ioctl HX170DEC_IOCGHWIOSIZE failed\n");
goto err;
}
DWL_DEBUG("SUCCESS\n");
return dec_dwl;
err:
DWL_DEBUG("FAILED\n");
DWLRelease(dec_dwl);
return NULL;
}
/*------------------------------------------------------------------------------
Function name : DWLRelease
Description : Release a DWl instance
Return type : i32 - 0 for success or a negative error code
Argument : const void * instance - instance to be released
------------------------------------------------------------------------------*/
i32 DWLRelease(const void *instance)
{
hX170dwl_t *dec_dwl = (hX170dwl_t *) instance;
configASSERT(dec_dwl != NULL);
vPortFree(dec_dwl);
DWL_DEBUG("SUCCESS\n");
return (DWL_OK);
}
/*******************************************************************************
Function name : DWLSetShareRamDecoder
Description : Set share ram for decode use
Return type : void
Argument : hx280ewl_t*
*******************************************************************************/
void DWLSetShareRamDecoder(hX170dwl_t * dwl)
{
}
/* HW locking */
/*------------------------------------------------------------------------------
Function name : DWLReserveHwPipe
Description :
Return type : i32
Argument : const void *instance
Argument : i32 *coreID - ID of the reserved HW core
------------------------------------------------------------------------------*/
i32 DWLReserveHwPipe(const void *instance/*, i32 *coreID*/)
{
i32 ret;
hX170dwl_t *dec_dwl = (hX170dwl_t *) instance;
i32 id = 0;
i32 *coreID = &id;
configASSERT(dec_dwl != NULL);
configASSERT(dec_dwl->clientType != DWL_CLIENT_TYPE_PP);
DWL_DEBUG("Start\n");
/* reserve decoder */
*coreID = vdec_ioctl(HX170DEC_IOCH_DEC_RESERVE, (void*)dec_dwl->clientType);
if (*coreID != 0)
{
return DWL_ERROR;
}
/* reserve PP */
ret = vdec_ioctl(HX170DEC_IOCQ_PP_RESERVE, NULL);
/* for pipeline we expect same core for both dec and PP */
if (ret != *coreID)
{
/* release the decoder */
vdec_ioctl( HX170DEC_IOCT_DEC_RELEASE, coreID);
return DWL_ERROR;
}
dec_dwl->bPPReserved = 1;
DWL_DEBUG("Reserved DEC+PP core %d\n", *coreID);
return DWL_OK;
}
/*------------------------------------------------------------------------------
Function name : DWLReserveHw
Description :
Return type : i32
Argument : const void *instance
Argument : i32 *coreID - ID of the reserved HW core
------------------------------------------------------------------------------*/
i32 DWLReserveHw(const void *instance/*, i32 *coreID*/)
{
hX170dwl_t *dec_dwl = (hX170dwl_t *) instance;
int isPP;
i32 id = 0;
i32 *coreID = &id;
configASSERT(dec_dwl != NULL);
isPP = dec_dwl->clientType == DWL_CLIENT_TYPE_PP ? 1 : 0;
DWL_DEBUG(" %s\n", isPP ? "PP" : "DEC");
if (isPP)
{
*coreID = vdec_ioctl(HX170DEC_IOCQ_PP_RESERVE, NULL);
/* PP is single core so we expect a zero return value */
if (*coreID != 0)
{
return DWL_ERROR;
}
}
else
{
*coreID = vdec_ioctl(HX170DEC_IOCH_DEC_RESERVE,
(void*)dec_dwl->clientType);
}
/* negative value signals an error */
if (*coreID < 0)
{
DWL_DEBUG("ioctl HX170DEC_IOCS_%s_RESERVE failed\n",
isPP ? "PP" : "DEC");
return DWL_ERROR;
}
#ifdef DEC_WITH_ENC
DWLSetShareRamDecoder(dec_dwl);
#endif
DWL_DEBUG("Reserved %s core %d\n", isPP ? "PP" : "DEC", *coreID);
return DWL_OK;
}
/*------------------------------------------------------------------------------
Function name : DWLReleaseHw
Description :
Return type : void
Argument : const void *instance
------------------------------------------------------------------------------*/
void DWLReleaseHw(const void *instance/*, i32 coreID*/)
{
hX170dwl_t *dec_dwl = (hX170dwl_t *) instance;
int isPP;
i32 coreID = 0;
configASSERT((u32)coreID < dec_dwl->numCores);
configASSERT(dec_dwl != NULL);
isPP = dec_dwl->clientType == DWL_CLIENT_TYPE_PP ? 1 : 0;
if ((u32) coreID >= dec_dwl->numCores)
return;
DWL_DEBUG(" %s core %d\n", isPP ? "PP" : "DEC", coreID);
if (isPP)
{
configASSERT(coreID == 0);
vdec_ioctl(HX170DEC_IOCT_PP_RELEASE, (void*)coreID);
}
else
{
if (dec_dwl->bPPReserved)
{
/* decoder has reserved PP also => release it */
DWL_DEBUG("DEC released PP core %d\n", coreID);
dec_dwl->bPPReserved = 0;
configASSERT(coreID == 0);
vdec_ioctl(HX170DEC_IOCT_PP_RELEASE, (void*)coreID);
}
vdec_ioctl(HX170DEC_IOCT_DEC_RELEASE, (void*)coreID);
}
}

View File

@ -0,0 +1,427 @@
/*------------------------------------------------------------------------------
-- --
-- This software is confidential and proprietary and may be used --
-- only as expressly authorized by a licensing agreement from --
-- --
-- Hantro Products Oy. --
-- --
-- (C) COPYRIGHT 2006 HANTRO PRODUCTS OY --
-- ALL RIGHTS RESERVED --
-- --
-- The entire notice above must be reproduced --
-- on all copies and should not be removed. --
-- --
--------------------------------------------------------------------------------
--
-- Description : H264 decoder and PP pipeline support
--
------------------------------------------------------------------------------
--
-- Version control information, please leave untouched.
--
-- $RCSfile: h264_pp_pipeline.c,v $
-- $Revision: 1.14 $
-- $Date: 2010/03/01 13:19:08 $
--
------------------------------------------------------------------------------*/
#include "basetype.h"
#include "h264_pp_pipeline.h"
#include "h264_pp_multibuffer.h"
#include "h264hwd_container.h"
#include "h264hwd_debug.h"
#include "h264hwd_util.h"
#ifndef TRACE_PP_CTRL
#define TRACE_PP_CTRL(...) do{}while(0)
#else
#undef TRACE_PP_CTRL
#define TRACE_PP_CTRL(...) printf(__VA_ARGS__)
#endif
/*------------------------------------------------------------------------------
Function name : h264RegisterPP
Description :
Return type : i32
Argument : const void * decInst
Argument : const void *ppInst
Argument : (*PPRun)(const void *)
Argument : void (*PPEndCallback)(const void *)
------------------------------------------------------------------------------*/
i32 h264RegisterPP(const void *decInst, const void *ppInst,
void (*PPDecStart) (const void *, const DecPpInterface *),
void (*PPDecWaitEnd) (const void *),
void (*PPConfigQuery) (const void *, DecPpQuery *),
void (*PPDisplayIndex) (const void *, u32))
{
decContainer_t *pDecCont;
pDecCont = (decContainer_t *) decInst;
if(decInst == NULL || pDecCont->pp.ppInstance != NULL ||
ppInst == NULL || PPDecStart == NULL || PPDecWaitEnd == NULL
|| PPConfigQuery == NULL)
{
TRACE_PP_CTRL("h264RegisterPP: Invalid parameter\n");
return -1;
}
if(pDecCont->asicRunning)
{
TRACE_PP_CTRL("h264RegisterPP: Illegal action, asicRunning\n");
return -2;
}
pDecCont->pp.ppInstance = ppInst;
pDecCont->pp.PPConfigQuery = PPConfigQuery;
pDecCont->pp.PPDecStart = PPDecStart;
pDecCont->pp.PPDecWaitEnd = PPDecWaitEnd;
pDecCont->pp.PPNextDisplayId = PPDisplayIndex;
pDecCont->pp.decPpIf.ppStatus = DECPP_IDLE;
pDecCont->pp.ppInfo.multiBuffer = 0;
h264PpMultiInit(pDecCont, 0);
pDecCont->storage.ppUsed = 1;
TRACE_PP_CTRL("h264RegisterPP: Connected to PP instance 0x%08x\n",
(size_t) ppInst);
return 0;
}
/*------------------------------------------------------------------------------
Function name : h264UnregisterPP
Description :
Return type : i32
Argument : const void * decInst
Argument : const void *ppInst
------------------------------------------------------------------------------*/
i32 h264UnregisterPP(const void *decInst, const void *ppInst)
{
decContainer_t *pDecCont;
pDecCont = (decContainer_t *) decInst;
ASSERT(decInst != NULL && ppInst == pDecCont->pp.ppInstance);
if(ppInst != pDecCont->pp.ppInstance)
{
TRACE_PP_CTRL("h264UnregisterPP: Invalid parameter\n");
return -1;
}
if(pDecCont->asicRunning)
{
TRACE_PP_CTRL("h264UnregisterPP: Illegal action, asicRunning\n");
return -2;
}
pDecCont->pp.ppInstance = NULL;
pDecCont->pp.PPConfigQuery = NULL;
pDecCont->pp.PPDecStart = NULL;
pDecCont->pp.PPDecWaitEnd = NULL;
TRACE_PP_CTRL("h264UnregisterPP: Disconnected from PP instance 0x%08x\n",
(size_t) ppInst);
return 0;
}
/*------------------------------------------------------------------------------
Function name : h264PreparePpRun
Description :
Return type : void
Argument : decContainer_t * pDecCont
------------------------------------------------------------------------------*/
void h264PreparePpRun(decContainer_t * pDecCont)
{
const storage_t *pStorage = &pDecCont->storage;
DecPpInterface *decPpIf = &pDecCont->pp.decPpIf;
const dpbStorage_t *dpb = pStorage->dpb;
/* PP not connected or still running (not waited when first field of frame
* finished */
if(pDecCont->pp.ppInstance == NULL ||
decPpIf->ppStatus == DECPP_PIC_NOT_FINISHED)
{
return;
}
if(dpb->noReordering && !dpb->numOut)
{
TRACE_PP_CTRL
("h264PreparePpRun: No reordering and no output => PP no run\n");
/* decoder could create fake pictures in DPB, which will never go to output.
* this is the case when new access unit detetcted but no valid slice decoded.
*/
return;
}
if(pDecCont->pp.ppInfo.multiBuffer == 0) /* legacy single buffer mode */
{
/* in some situations, like field decoding,
* the dpb->numOut is not reset, but, dpb->numOut == dpb->outIndex */
if(dpb->numOut != 0) /* we have output */
{
TRACE_PP_CTRL
("h264PreparePpRun: output picture => PP could run!\n");
if(dpb->outBuf[dpb->outIndexR].data == pStorage->currImage->data)
{
/* we could have pipeline */
TRACE_PP_CTRL("h264PreparePpRun: decode == output\n");
if(pStorage->activeSps->frameMbsOnlyFlag == 0 &&
pStorage->secondField)
{
TRACE_PP_CTRL
("h264PreparePpRun: first field only! Do not run PP, yet!\n");
return;
}
if(pStorage->currImage->picStruct != FRAME)
{
u32 opposit_field = pStorage->currImage->picStruct ^ 1;
if(dpb->currentOut->status[opposit_field] != EMPTY)
{
decPpIf->usePipeline = 0;
TRACE_PP_CTRL
("h264PreparePpRun: second field of frame! Pipeline cannot be used!\n");
}
}
else if(!pStorage->activeSps->mbAdaptiveFrameFieldFlag)
{
decPpIf->usePipeline =
pDecCont->pp.ppInfo.pipelineAccepted & 1;
}
else
decPpIf->usePipeline = 0;
if(decPpIf->usePipeline)
{
TRACE_PP_CTRL
("h264PreparePpRun: pipeline=ON => PP will be running\n");
decPpIf->ppStatus = DECPP_RUNNING;
if(!pStorage->prevNalUnit->nalRefIdc)
{
pDecCont->asicBuff->disableOutWriting = 1;
TRACE_PP_CTRL
("h264PreparePpRun: Not reference => Disable decoder output writing\n");
}
}
else
{
TRACE_PP_CTRL
("h264PreparePpRun: pipeline=OFF => PP has to run after DEC\n");
}
}
else
{
decPpIf->ppStatus = DECPP_RUNNING;
decPpIf->usePipeline = 0;
TRACE_PP_CTRL
("h264PreparePpRun: decode != output => pipeline=OFF => PP run in parallel\n");
}
}
else
{
TRACE_PP_CTRL
("h264PreparePpRun: no output picture => PP no run!\n");
}
return;
}
/* multibuffer mode */
TRACE_PP_CTRL("h264PreparePpRun: MULTIBUFFER!\n");
if(pDecCont->pp.queuedPicToPp == NULL &&
pStorage->activeSps->frameMbsOnlyFlag == 0 && pStorage->secondField)
{
TRACE_PP_CTRL
("h264PreparePpRun: no queued picture and first field only! Do not run PP, yet!\n");
return;
}
if(pDecCont->pp.queuedPicToPp == NULL &&
pStorage->currentMarked == HANTRO_FALSE)
{
TRACE_PP_CTRL
("h264PreparePpRun: no queued picture and current pic NOT for display! Do not run PP!\n");
return;
}
if(pStorage->currImage->picStruct != FRAME)
{
TRACE_PP_CTRL("h264PreparePpRun: 2 Fields! Pipeline cannot be used!\n");
/* we shall not have EMPTY output marked for display, missing fields are acceptable */
ASSERT((pDecCont->pp.queuedPicToPp != NULL) ||
(dpb->currentOut->status[0] != EMPTY) ||
(dpb->currentOut->status[1] != EMPTY));
decPpIf->usePipeline = 0;
}
else if(!pStorage->activeSps->mbAdaptiveFrameFieldFlag)
{
decPpIf->usePipeline = pDecCont->pp.ppInfo.pipelineAccepted & 1;
}
else
decPpIf->usePipeline = 0;
if(decPpIf->usePipeline)
{
decPpIf->ppStatus = DECPP_RUNNING;
TRACE_PP_CTRL
("h264PreparePpRun: pipeline=ON => PP will be running\n");
}
else
{
if(pDecCont->pp.queuedPicToPp != NULL)
{
decPpIf->ppStatus = DECPP_RUNNING;
TRACE_PP_CTRL
("h264PreparePpRun: pipeline=OFF, queued picture => PP run in parallel\n");
}
else
{
TRACE_PP_CTRL
("h264PreparePpRun: pipeline=OFF, no queued picture => PP no run\n");
/* do not process pictures added to DPB but not intended for display */
if(dpb->noReordering ||
dpb->currentOut->toBeDisplayed == HANTRO_TRUE)
{
if(!pStorage->secondField) /* do not queue first field */
{
pDecCont->pp.queuedPicToPp = dpb->currentOut->data;
}
}
}
}
}
/*------------------------------------------------------------------------------
Function name : h264PpMultiAddPic
Description : Add a new picture to the PP processed table (frist free place).
Return the tabel position where added.
Return type : u32
Argument : decContainer_t * pDecCont
Argument : const DWLLinearMem_t * data
------------------------------------------------------------------------------*/
u32 h264PpMultiAddPic(decContainer_t * pDecCont, const DWLLinearMem_t * data)
{
u32 nextFreeId;
ASSERT(pDecCont->pp.ppInfo.multiBuffer != 0);
for(nextFreeId = 0; nextFreeId <= pDecCont->pp.multiMaxId; nextFreeId++)
{
if(pDecCont->pp.sentPicToPp[nextFreeId] == NULL)
{
break;
}
}
ASSERT(nextFreeId <= pDecCont->pp.multiMaxId);
if(nextFreeId <= pDecCont->pp.multiMaxId)
pDecCont->pp.sentPicToPp[nextFreeId] = data;
return nextFreeId;
}
/*------------------------------------------------------------------------------
Function name : h264PpMultiRemovePic
Description : Reomove a picture form the PP processed list.
Return the position which was emptied.
Return type : u32
Argument : decContainer_t * pDecCont
Argument : const DWLLinearMem_t * data
------------------------------------------------------------------------------*/
u32 h264PpMultiRemovePic(decContainer_t * pDecCont, const DWLLinearMem_t * data)
{
u32 picId;
ASSERT(pDecCont->pp.ppInfo.multiBuffer != 0);
for(picId = 0; picId <= pDecCont->pp.multiMaxId; picId++)
{
if(pDecCont->pp.sentPicToPp[picId] == data)
{
break;
}
}
ASSERT(picId <= pDecCont->pp.multiMaxId);
if(picId <= pDecCont->pp.multiMaxId)
pDecCont->pp.sentPicToPp[picId] = NULL;
return picId;
}
/*------------------------------------------------------------------------------
Function name : h264PpMultiFindPic
Description : Find a picture in the PP processed list. If found, return
the position. If not found, return an value bigger than
the max.
Return type : u32
Argument : decContainer_t * pDecCont
Argument : const DWLLinearMem_t * data
------------------------------------------------------------------------------*/
u32 h264PpMultiFindPic(decContainer_t * pDecCont, const DWLLinearMem_t * data)
{
u32 picId;
ASSERT(pDecCont->pp.ppInfo.multiBuffer != 0);
for(picId = 0; picId <= pDecCont->pp.multiMaxId; picId++)
{
if(pDecCont->pp.sentPicToPp[picId] == data)
{
break;
}
}
return picId;
}
/*------------------------------------------------------------------------------
Function name : h264PpMultiInit
Description : Initialize the PP processed list.
Return type : void
Argument : decContainer_t * pDecCont
Argument : u32 maxBuffId - max ID in use (buffs = (maxBuffId + 1))
------------------------------------------------------------------------------*/
void h264PpMultiInit(decContainer_t * pDecCont, u32 maxBuffId)
{
u32 i;
const u32 buffs =
sizeof(pDecCont->pp.sentPicToPp) / sizeof(*pDecCont->pp.sentPicToPp);
ASSERT(maxBuffId < buffs);
pDecCont->pp.queuedPicToPp = NULL;
pDecCont->pp.multiMaxId = maxBuffId;
for(i = 0; i < buffs; i++)
{
pDecCont->pp.sentPicToPp[i] = NULL;
}
}
u32 h264UseDisplaySmoothing(const void *decInst)
{
decContainer_t *pDecCont = (decContainer_t*)decInst;
if (pDecCont->storage.useSmoothing)
return HANTRO_TRUE;
else
return HANTRO_FALSE;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,81 @@
/*------------------------------------------------------------------------------
-- --
-- This software is confidential and proprietary and may be used --
-- only as expressly authorized by a licensing agreement from --
-- --
-- Hantro Products Oy. --
-- --
-- (C) COPYRIGHT 2006 HANTRO PRODUCTS OY --
-- ALL RIGHTS RESERVED --
-- --
-- The entire notice above must be reproduced --
-- on all copies and should not be removed. --
-- --
--------------------------------------------------------------------------------
--
-- Abstract : Application Programming Interface (API) extension
--
--------------------------------------------------------------------------------
--
-- Version control information, please leave untouched.
--
-- $RCSfile: h264decapi_e.c,v $
-- $Date: 2009/06/05 10:57:15 $
-- $Revision: 1.2 $
--
------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------
1. Include headers
------------------------------------------------------------------------------*/
#include "basetype.h"
#include "h264hwd_container.h"
#include "h264decapi_e.h"
/*------------------------------------------------------------------------------
Function: H264DecNextChPicture
Functional description:
Input:
decInst decoder instance.
Output:
pOutput pointer to output structure
Returns:
H264DEC_OK no pictures available for display
H264DEC_PIC_RDY picture available for display
H264DEC_PARAM_ERROR invalid parameters
------------------------------------------------------------------------------*/
H264DecRet H264DecNextChPicture(H264DecInst decInst,
u32 **pOutput, u32 *busAddr)
{
decContainer_t *pDecCont = (decContainer_t *) decInst;
if(decInst == NULL || pOutput == NULL || busAddr == NULL)
{
return (H264DEC_PARAM_ERROR);
}
/* Check for valid decoder instance */
if(pDecCont->checksum != pDecCont)
{
return (H264DEC_NOT_INITIALIZED);
}
if (pDecCont->storage.enable2ndChroma && pDecCont->storage.pCh2)
{
*pOutput = pDecCont->storage.pCh2;
*busAddr = pDecCont->storage.bCh2;
return (H264DEC_PIC_RDY);
}
else
{
return (H264DEC_OK);
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,297 @@
/*------------------------------------------------------------------------------
-- --
-- This software is confidential and proprietary and may be used --
-- only as expressly authorized by a licensing agreement from --
-- --
-- Hantro Products Oy. --
-- --
-- (C) COPYRIGHT 2006 HANTRO PRODUCTS OY --
-- ALL RIGHTS RESERVED --
-- --
-- The entire notice above must be reproduced --
-- on all copies and should not be removed. --
-- --
--------------------------------------------------------------------------------
--
-- Abstract : Extract a NAL unit from byte stream
--
--------------------------------------------------------------------------------
--
-- Version control information, please leave untouched.
--
-- $RCSfile: h264hwd_byte_stream.c,v $
-- $Date: 2008/09/11 08:32:04 $
-- $Revision: 1.2 $
--
------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------
1. Include headers
------------------------------------------------------------------------------*/
#include "h264hwd_byte_stream.h"
#include "h264hwd_util.h"
/*------------------------------------------------------------------------------
2. External compiler flags
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
3. Module defines
------------------------------------------------------------------------------*/
#define BYTE_STREAM_ERROR 0xFFFFFFFF
/*------------------------------------------------------------------------------
4. Local function prototypes
------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------
Function name: ExtractNalUnit
Functional description:
Extracts one NAL unit from the byte stream buffer. Removes
emulation prevention bytes if present. The original stream buffer
is used directly and is therefore modified if emulation prevention
bytes are present in the stream.
Stream buffer is assumed to contain either exactly one NAL unit
and nothing else, or one or more NAL units embedded in byte
stream format described in the Annex B of the standard. Function
detects which one is used based on the first bytes in the buffer.
Inputs:
pByteStream pointer to byte stream buffer
len length of the stream buffer (in bytes)
Outputs:
pStrmData stream information is stored here
readBytes number of bytes "consumed" from the stream buffer
Returns:
HANTRO_OK success
HANTRO_NOK error in byte stream
------------------------------------------------------------------------------*/
u32 h264bsdExtractNalUnit(const u8 * pByteStream, u32 len,
strmData_t * pStrmData, u32 * readBytes, u32 rlcMode)
{
/* Variables */
u32 byteCount, initByteCount;
u32 zeroCount;
u8 byte;
u32 invalidStream = HANTRO_FALSE;
u32 hasEmulation = HANTRO_FALSE;
const u8 *readPtr;
/* Code */
ASSERT(pByteStream);
ASSERT(len);
ASSERT(len < BYTE_STREAM_ERROR);
ASSERT(pStrmData);
/* byte stream format if starts with 0x000001 or 0x000000 */
if(len > 3 && pByteStream[0] == 0x00 && pByteStream[1] == 0x00 &&
(pByteStream[2] & 0xFE) == 0x00)
{
DEBUG_PRINT(("BYTE STREAM detected\n"));
/* search for NAL unit start point, i.e. point after first start code
* prefix in the stream */
zeroCount = byteCount = 2;
readPtr = pByteStream + 2;
/*lint -e(716) while(1) used consciously */
while(1)
{
byte = *readPtr++;
byteCount++;
if(byteCount == len)
{
/* no start code prefix found -> error */
*readBytes = len;
ERROR_PRINT("NO START CODE PREFIX");
return (HANTRO_NOK);
}
if(!byte)
zeroCount++;
else if((byte == 0x01) && (zeroCount >= 2))
break;
else
zeroCount = 0;
}
initByteCount = byteCount;
#if 1
if(!rlcMode)
{
pStrmData->pStrmBuffStart = pByteStream + initByteCount;
pStrmData->pStrmCurrPos = pStrmData->pStrmBuffStart;
pStrmData->bitPosInWord = 0;
pStrmData->strmBuffReadBits = 0;
pStrmData->strmBuffSize = len - initByteCount;
*readBytes = len;
return (HANTRO_OK);
}
#endif
/* determine size of the NAL unit. Search for next start code prefix
* or end of stream and ignore possible trailing zero bytes */
zeroCount = 0;
/*lint -e(716) while(1) used consciously */
while(1)
{
byte = *readPtr++;
byteCount++;
if(!byte)
zeroCount++;
else
{
if((byte == 0x03) && (zeroCount == 2))
{
hasEmulation = HANTRO_TRUE;
}
else if((byte == 0x01) && (zeroCount >= 2))
{
pStrmData->strmBuffSize =
byteCount - initByteCount - zeroCount - 1;
zeroCount -= MIN(zeroCount, 3);
break;
}
if(zeroCount >= 3)
invalidStream = HANTRO_TRUE;
zeroCount = 0;
}
if(byteCount == len)
{
pStrmData->strmBuffSize = byteCount - initByteCount - zeroCount;
break;
}
}
}
/* separate NAL units as input -> just set stream params */
else
{
DEBUG_PRINT(("SINGLE NAL unit detected\n"));
initByteCount = 0;
zeroCount = 0;
pStrmData->strmBuffSize = len;
hasEmulation = HANTRO_TRUE;
}
pStrmData->pStrmBuffStart = pByteStream + initByteCount;
pStrmData->pStrmCurrPos = pStrmData->pStrmBuffStart;
pStrmData->bitPosInWord = 0;
pStrmData->strmBuffReadBits = 0;
/* return number of bytes "consumed" */
*readBytes = pStrmData->strmBuffSize + initByteCount + zeroCount;
if(invalidStream)
{
ERROR_PRINT("INVALID STREAM");
return (HANTRO_NOK);
}
/* remove emulation prevention bytes before rbsp processing */
if(hasEmulation && pStrmData->removeEmul3Byte)
{
i32 i = pStrmData->strmBuffSize;
u8 *writePtr = (u8 *) pStrmData->pStrmBuffStart;
readPtr = pStrmData->pStrmBuffStart;
zeroCount = 0;
while(i--)
{
if((zeroCount == 2) && (*readPtr == 0x03))
{
/* emulation prevention byte shall be followed by one of the
* following bytes: 0x00, 0x01, 0x02, 0x03. This implies that
* emulation prevention 0x03 byte shall not be the last byte
* of the stream. */
if((i == 0) || (*(readPtr + 1) > 0x03))
return (HANTRO_NOK);
DEBUG_PRINT(("EMULATION PREVENTION 3 BYTE REMOVED\n"));
/* do not write emulation prevention byte */
readPtr++;
zeroCount = 0;
}
else
{
/* NAL unit shall not contain byte sequences 0x000000,
* 0x000001 or 0x000002 */
if((zeroCount == 2) && (*readPtr <= 0x02))
return (HANTRO_NOK);
if(*readPtr == 0)
zeroCount++;
else
zeroCount = 0;
*writePtr++ = *readPtr++;
}
}
/* (readPtr - writePtr) indicates number of "removed" emulation
* prevention bytes -> subtract from stream buffer size */
pStrmData->strmBuffSize -= (u32) (readPtr - writePtr);
}
return (HANTRO_OK);
}
/*------------------------------------------------------------------------------
Function name : h264bsdFindNextStartCode
Description :
Return type : const u8 *
Argument : const u8 * pByteStream
Argument : u32 len
------------------------------------------------------------------------------*/
const u8 *h264bsdFindNextStartCode(const u8 * pByteStream, u32 len)
{
u32 byteCount = 0;
u32 zeroCount = 0;
const u8 *start = NULL;
/* determine size of the NAL unit. Search for next start code prefix
* or end of stream */
/* start from second byte */
pByteStream++;
len--;
while(byteCount++ < len)
{
u32 byte = *pByteStream++;
if(byte == 0)
zeroCount++;
else
{
if((byte == 0x01) && (zeroCount >= 2))
{
start = pByteStream - MIN(zeroCount, 3) - 1;
break;
}
zeroCount = 0;
}
}
return start;
}

View File

@ -0,0 +1,186 @@
/*------------------------------------------------------------------------------
-- --
-- This software is confidential and proprietary and may be used --
-- only as expressly authorized by a licensing agreement from --
-- --
-- Hantro Products Oy. --
-- --
-- (C) COPYRIGHT 2006 HANTRO PRODUCTS OY --
-- ALL RIGHTS RESERVED --
-- --
-- The entire notice above must be reproduced --
-- on all copies and should not be removed. --
-- --
--------------------------------------------------------------------------------
--
-- Description : CABAC initialization tables.
--
------------------------------------------------------------------------------
--
-- Version control information, please leave untouched.
--
-- $RCSfile: h264hwd_cabac.c,v $
-- $Revision: 1.1 $
-- $Date: 2008/03/13 12:48:06 $
--
------------------------------------------------------------------------------*/
#include "basetype.h"
const u32 cabacInitValues[4*460*2/4] =
{
0x14f10236, 0x034a14f1, 0x0236034a, 0xe47fe968, 0xfa35ff36, 0x07330000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x0029003f, 0x003f003f, 0xf7530456, 0x0061f948, 0x0d29033e, 0x000b0137,
0x0045ef7f, 0xf3660052, 0xf94aeb6b, 0xe57fe17f, 0xe87fee5f, 0xe57feb72,
0xe27fef7b, 0xf473f07a, 0xf573f43f, 0xfe44f154, 0xf368fd46, 0xf85df65a,
0xe27fff4a, 0xfa61f95b, 0xec7ffc38, 0xfb52f94c, 0xea7df95d, 0xf557fd4d,
0xfb47fc3f, 0xfc44f454, 0xf93ef941, 0x083d0538, 0xfe420140, 0x003dfe4e,
0x01320734, 0x0a23002c, 0x0b26012d, 0x002e052c, 0x1f110133, 0x07321c13,
0x10210e3e, 0xf36cf164, 0xf365f35b, 0xf45ef658, 0xf054f656, 0xf953f357,
0xed5e0146, 0x0048fb4a, 0x123bf866, 0xf164005f, 0xfc4b0248, 0xf54bfd47,
0x0f2ef345, 0x003e0041, 0x1525f148, 0x09391036, 0x003e0c48, 0x18000f09,
0x08190d12, 0x0f090d13, 0x0a250c12, 0x061d1421, 0x0f1e042d, 0x013a003e,
0x073d0c26, 0x0b2d0f27, 0x0b2a0d2c, 0x102d0c29, 0x0a311e22, 0x122a0a37,
0x1133112e, 0x00591aed, 0x16ef1aef, 0x1ee71cec, 0x21e925e5, 0x21e928e4,
0x26ef21f5, 0x28f129fa, 0x26012911, 0x1efa1b03, 0x1a1625f0, 0x23fc26f8,
0x26fd2503, 0x26052a00, 0x23102716, 0x0e301b25, 0x153c0c44, 0x0261fd47,
0xfa2afb32, 0xfd36fe3e, 0x003a013f, 0xfe48ff4a, 0xf75bfb43, 0xfb1bfd27,
0xfe2c002e, 0xf040f844, 0xf64efa4d, 0xf656f45c, 0xf137f63c, 0xfa3efc41,
0xf449f84c, 0xf950f758, 0xef6ef561, 0xec54f54f, 0xfa49fc4a, 0xf356f360,
0xf561ed75, 0xf84efb21, 0xfc30fe35, 0xfd3ef347, 0xf64ff456, 0xf35af261,
0x0000fa5d, 0xfa54f84f, 0x0042ff47, 0x003efe3c, 0xfe3bfb4b, 0xfd3efc3a,
0xf742ff4f, 0x00470344, 0x0a2cf93e, 0x0f240e28, 0x101b0c1d, 0x012c1424,
0x1220052a, 0x01300a3e, 0x112e0940, 0xf468f561, 0xf060f958, 0xf855f955,
0xf755f358, 0x0442fd4d, 0xfd4cfa4c, 0x0a3aff4c, 0xff53f963, 0xf25f025f,
0x004cfb4a, 0x0046f54b, 0x01440041, 0xf249033e, 0x043eff44, 0xf34b0b37,
0x05400c46, 0x0f060613, 0x07100c0e, 0x120d0d0b, 0x0d0f0f10, 0x0c170d17,
0x0f140e1a, 0x0e2c1128, 0x112f1811, 0x15151916, 0x1f1b161d, 0x13230e32,
0x0a39073f, 0xfe4dfc52, 0xfd5e0945, 0xf46d24dd, 0x24de20e6, 0x25e22ce0,
0x22ee22f1, 0x28f121f9, 0x23fb2100, 0x2602210d, 0x17230d3a, 0x1dfd1a00,
0x161e1ff9, 0x23f122fd, 0x220324ff, 0x2205200b, 0x2305220c, 0x270b1e1d,
0x221a1d27, 0x13421f15, 0x1f1f1932, 0xef78ec70, 0xee72f555, 0xf15cf259,
0xe647f151, 0xf2500044, 0xf246e838, 0xe944e832, 0xf54a17f3, 0x1af328f1,
0x31f22c03, 0x2d062c22, 0x21361352, 0xfd4bff17, 0x0122012b, 0x0036fe37,
0x003d0140, 0x0044f75c, 0xf26af361, 0xf15af45a, 0xee58f649, 0xf74ff256,
0xf649f646, 0xf645fb42, 0xf740fb3a, 0x023b15f6, 0x18f51cf8, 0x1cff1d03,
0x1d092314, 0x1d240e43, 0x14f10236, 0x034a14f1, 0x0236034a, 0xe47fe968,
0xfa35ff36, 0x07331721, 0x17021500, 0x01090031, 0xdb760539, 0xf34ef541,
0x013e0c31, 0xfc491132, 0x1240092b, 0x1d001a43, 0x105a0968, 0xd27fec68,
0x0143f34e, 0xf541013e, 0xfa56ef5f, 0xfa3d092d, 0xfd45fa51, 0xf5600637,
0x0743fb56, 0x0258003a, 0xfd4cf65e, 0x05360445, 0xfd510058, 0xf943fb4a,
0xfc4afb50, 0xf948013a, 0x0029003f, 0x003f003f, 0xf7530456, 0x0061f948,
0x0d29033e, 0x002dfc4e, 0xfd60e57e, 0xe462e765, 0xe943e452, 0xec5ef053,
0xea6eeb5b, 0xee66f35d, 0xe37ff95c, 0xfb59f960, 0xf36cfd2e, 0xff41ff39,
0xf75dfd4a, 0xf75cf857, 0xe97e0536, 0x063c063b, 0x0645ff30, 0x0044fc45,
0xf858fe55, 0xfa4eff4b, 0xf94d0236, 0x0532fd44, 0x0132062a, 0xfc51013f,
0xfc460043, 0x0239fe4c, 0x0b230440, 0x013d0b23, 0x12190c18, 0x0d1d0d24,
0xf65df949, 0xfe490d2e, 0x0931f964, 0x09350235, 0x0535fe3d, 0x00380038,
0xf33ffb3c, 0xff3e0439, 0xfa450439, 0x0e270433, 0x0d440340, 0x013d093f,
0x07321027, 0x052c0434, 0x0b30fb3c, 0xff3b003b, 0x1621052c, 0x0e2bff4e,
0x003c0945, 0x0b1c0228, 0x032c0031, 0x002e022c, 0x0233002f, 0x0427023e,
0x062e0036, 0x0336023a, 0x043f0633, 0x06390735, 0x06340637, 0x0b2d0e24,
0x0835ff52, 0x0737fd4e, 0x0f2e161f, 0xff541907, 0x1ef91c03, 0x1c042000,
0x22ff1e06, 0x1e062009, 0x1f131a1b, 0x1a1e2514, 0x1c221146, 0x0143053b,
0x0943101e, 0x12201223, 0x161d181f, 0x1726122b, 0x14290b3f, 0x093b0940,
0xff5efe59, 0xf76cfa4c, 0xfe2c002d, 0x0034fd40, 0xfe3bfc46, 0xfc4bf852,
0xef66f74d, 0x0318002a, 0x00300037, 0xfa3bf947, 0xf453f557, 0xe277013a,
0xfd1dff24, 0x0126022b, 0xfa37003a, 0x0040fd4a, 0xf65a0046, 0xfc1d051f,
0x072a013b, 0xfe3afd48, 0xfd51f561, 0x003a0805, 0x0a0e0e12, 0x0d1b0228,
0x003afd46, 0xfa4ff855, 0x0000f36a, 0xf06af657, 0xeb72ee6e, 0xf262ea6e,
0xeb6aee67, 0xeb6be96c, 0xe670f660, 0xf45ffb5b, 0xf75dea5e, 0xfb560943,
0xfc50f655, 0xff46073c, 0x093a053d, 0x0c320f32, 0x12311136, 0x0a29072e,
0xff330731, 0x08340929, 0x062f0237, 0x0d290a2c, 0x06320535, 0x0d31043f,
0x0640fe45, 0xfe3b0646, 0x0a2c091f, 0x0c2b0335, 0x0e220a26, 0xfd340d28,
0x1120072c, 0x07260d32, 0x0a391a2b, 0x0e0b0b0e, 0x090b120b, 0x150917fe,
0x20f120f1, 0x22eb27e9, 0x2adf29e1, 0x2ee426f4, 0x151d2de8, 0x35d330e6,
0x41d52bed, 0x27f61e09, 0x121a141b, 0x0039f252, 0xfb4bed61, 0xdd7d1b00,
0x1c001ffc, 0x1b062208, 0x1e0a1816, 0x21131620, 0x1a1f1529, 0x1a2c172f,
0x10410e47, 0x083c063f, 0x11411518, 0x17141a17, 0x1b201c17, 0x1c181728,
0x18201c1d, 0x172a1339, 0x1635163d, 0x0b560c28, 0x0b330e3b, 0xfc4ff947,
0xfb45f746, 0xf842f644, 0xed49f445, 0xf046f143, 0xec3eed46, 0xf042ea41,
0xec3f09fe, 0x1af721f7, 0x27f929fe, 0x2d033109, 0x2d1b243b, 0xfa42f923,
0xf92af82d, 0xfb30f438, 0xfa3cfb3e, 0xf842f84c, 0xfb55fa51, 0xf64df951,
0xef50ee49, 0xfc4af653, 0xf747f743, 0xff3df842, 0xf242003b, 0x023b15f3,
0x21f227f9, 0x2efe3302, 0x3c063d11, 0x37222a3e, 0x14f10236, 0x034a14f1,
0x0236034a, 0xe47fe968, 0xfa35ff36, 0x07331619, 0x22001000, 0xfe090429,
0xe3760241, 0xfa47f34f, 0x05340932, 0xfd460a36, 0x1a221316, 0x28003902,
0x29241a45, 0xd37ff165, 0xfc4cfa47, 0xf34f0534, 0x0645f35a, 0x0034082b,
0xfe45fb52, 0xf660023b, 0x024bfd57, 0xfd640138, 0xfd4afa55, 0x003bfd51,
0xf956fb5f, 0xff42ff4d, 0x0146fe56, 0xfb48003d, 0x0029003f, 0x003f003f,
0xf7530456, 0x0061f948, 0x0d29033e, 0x0d0f0733, 0x0250d97f, 0xee5bef60,
0xe651dd62, 0xe866e961, 0xe577e863, 0xeb6eee66, 0xdc7f0050, 0xfb59f95e,
0xfc5c0027, 0x0041f154, 0xdd7ffe49, 0xf468f75b, 0xe17f0337, 0x07380737,
0x083dfd35, 0x0044f94a, 0xf758f367, 0xf35bf759, 0xf25cf84c, 0xf457e96e,
0xe869f64e, 0xec70ef63, 0xb27fba7f, 0xce7fd27f, 0xfc42fb4e, 0xfc47f848,
0x023bff37, 0xf946fa4b, 0xf859de77, 0xfd4b2014, 0x1e16d47f, 0x0036fb3d,
0x003aff3c, 0xfd3df843, 0xe754f24a, 0xfb410534, 0x0239003d, 0xf745f546,
0x1237fc47, 0x003a073d, 0x09291219, 0x0920052b, 0x092f002c, 0x0033022e,
0x1326fc42, 0x0f260c2a, 0x09220059, 0x042d0a1c, 0x0a1f21f5, 0x34d5120f,
0x1c0023ea, 0x26e72200, 0x27ee20f4, 0x66a20000, 0x38f121fc, 0x1d0a25fb,
0x33e327f7, 0x34de45c6, 0x43c12cfb, 0x200737e3, 0x20010000, 0x1b2421e7,
0x22e224e4, 0x26e426e5, 0x22ee23f0, 0x22f220f8, 0x25fa2300, 0x1e0a1c12,
0x1a191d29, 0x004b0248, 0x084d0e23, 0x121f1123, 0x151e112d, 0x142a122d,
0x1b1a1036, 0x07421038, 0x0b490a43, 0xf674e970, 0xf147f93d, 0x0035fb42,
0xf54df750, 0xf754f657, 0xde7feb65, 0xfd27fb35, 0xf93df54b, 0xf14def5b,
0xe76be76f, 0xe47af54c, 0xf62cf634, 0xf639f73a, 0xf048f945, 0xfc45fb4a,
0xf7560242, 0xf7220120, 0x0b1f0534, 0xfe37fe43, 0x0049f859, 0x03340704,
0x0a081108, 0x10130325, 0xff3dfb49, 0xff46fc4e, 0x0000eb7e, 0xe97cec6e,
0xe67ee77c, 0xef69e579, 0xe575ef66, 0xe675e574, 0xdf7af65f, 0xf264f85f,
0xef6fe472, 0xfa59fe50, 0xfc52f755, 0xf851ff48, 0x05400143, 0x09380045,
0x01450745, 0xf945fa43, 0xf04dfe40, 0x023dfa43, 0xfd400239, 0xfd41fd42,
0x003e0933, 0xff42fe47, 0xfe4bff46, 0xf7480e3c, 0x1025002f, 0x12230b25,
0x0c290a29, 0x02300c29, 0x0d29003b, 0x03321328, 0x03421232, 0x13fa12fa,
0x0e001af4, 0x1ff021e7, 0x21ea25e4, 0x27e22ae2, 0x2fd62ddc, 0x31de29ef,
0x200945b9, 0x3fc142c0, 0x4db636d9, 0x34dd29f6, 0x240028ff, 0x1e0e1c1a,
0x17250c37, 0x0b4125df, 0x27dc28db, 0x26e22edf, 0x2ae228e8, 0x31e326f4,
0x28f626fd, 0x2efb1f14, 0x1d1e192c, 0x0c300b31, 0x1a2d1616, 0x17161b15,
0x21141a1c, 0x1e181b22, 0x122a1927, 0x12320c46, 0x15360e47, 0x0b531920,
0x15311536, 0xfb55fa51, 0xf64df951, 0xef50ee49, 0xfc4af653, 0xf747f743,
0xff3df842, 0xf242003b, 0x023b11f6, 0x20f32af7, 0x31fb3500, 0x4003440a,
0x421b2f39, 0xfb470018, 0xff24fe2a, 0xfe34f739, 0xfa3ffc41, 0xfc43f952,
0xfd51fd4c, 0xf948fa4e, 0xf448f244, 0xfd46fa4c, 0xfb42fb3e, 0x0039fc3d,
0xf73c0136, 0x023a11f6, 0x20f32af7, 0x31fb3500, 0x4003440a, 0x421b2f39,
0x14f10236, 0x034a14f1, 0x0236034a, 0xe47fe968, 0xfa35ff36, 0x07331d10,
0x19000e00, 0xf633fd3e, 0xe5631a10, 0xfc55e866, 0x05390639, 0xef490e39,
0x1428140a, 0x1d003600, 0x252a0c61, 0xe07fea75, 0xfe4afc55, 0xe8660539,
0xfa5df258, 0xfa2c0437, 0xf559f167, 0xeb741339, 0x143a0454, 0x0660013f,
0xfb55f36a, 0x053f064b, 0xfd5aff65, 0x0337fc4f, 0xfe4bf461, 0xf932013c,
0x0029003f, 0x003f003f, 0xf7530456, 0x0061f948, 0x0d29033e, 0x0722f758,
0xec7fdc7f, 0xef5bf25f, 0xe754e756, 0xf459ef5b, 0xe17ff24c, 0xee67f35a,
0xdb7f0b50, 0x054c0254, 0x054efa37, 0x043df253, 0xdb7ffb4f, 0xf568f55b,
0xe27f0041, 0xfe4f0048, 0xfc5cfa38, 0x0344f847, 0xf362fc56, 0xf458fb52,
0xfd48fc43, 0xf848f059, 0xf745ff3b, 0x05420439, 0xfc47fe47, 0x023aff4a,
0xfc2cff45, 0x003ef933, 0xfc2ffa2a, 0xfd29fa35, 0x084cf74e, 0xf5530934,
0x0043fb5a, 0x0143f148, 0xfb4bf850, 0xeb53eb40, 0xf31fe740, 0xe35e094b,
0x113ff84a, 0xfb23fe1b, 0x0d5b0341, 0xf945084d, 0xf642033e, 0xfd44ec51,
0x001e0107, 0xfd17eb4a, 0x1042e97c, 0x11252cee, 0x32deea7f, 0x0427002a,
0x07220b1d, 0x081f0625, 0x072a0328, 0x08210d2b, 0x0d24042f, 0x0337023a,
0x063c082c, 0x0b2c0e2a, 0x07300438, 0x04340d25, 0x0931133a, 0x0a300c2d,
0x00451421, 0x083f23ee, 0x21e71cfd, 0x180a1b00, 0x22f234d4, 0x27e81311,
0x1f19241d, 0x1821220f, 0x1e141649, 0x1422131f, 0x1b2c1310, 0x0f240f24,
0x151c1915, 0x1e141f0c, 0x1b10182a, 0x005d0e38, 0x0f391a26, 0xe87fe873,
0xea52f73e, 0x0035003b, 0xf255f359, 0xf35ef55c, 0xe37feb64, 0xf239f443,
0xf547f64d, 0xeb55f058, 0xe968f162, 0xdb7ff652, 0xf830f83d, 0xf842f946,
0xf24bf64f, 0xf753f45c, 0xee6cfc4f, 0xea45f04b, 0xfe3a013a, 0xf34ef753,
0xfc51f363, 0xf351fa26, 0xf33efa3a, 0xfe3bf049, 0xf64cf356, 0xf753f657,
0x0000ea7f, 0xe77fe778, 0xe57fed72, 0xe975e776, 0xe675e871, 0xe476e178,
0xdb7cf65e, 0xf166f663, 0xf36ace7f, 0xfb5c1139, 0xfb56f35e, 0xf45bfe4d,
0x0047ff49, 0x0440f951, 0x05400f39, 0x01430044, 0xf6430144, 0x004d0240,
0x0044fb4e, 0x0737053b, 0x02410e36, 0x0f2c053c, 0x0246fe4c, 0xee560c46,
0x0540f446, 0x0b370538, 0x00450241, 0xfa4a0536, 0x0736fa4c, 0xf552fe4d,
0xfe4d192a, 0x11f310f7, 0x11f41beb, 0x25e229d8, 0x2ad730d1, 0x27e02ed8,
0x34cd2ed7, 0x34d92bed, 0x200b3dc9, 0x38d23ece, 0x51bd2dec, 0x23fe1c0f,
0x22012701, 0x1e111426, 0x122d0f36, 0x004f24f0, 0x25f225ef, 0x2001220f,
0x1d0f1819, 0x22161f10, 0x23121f1c, 0x2129241c, 0x1b2f153e, 0x121f131a,
0x24181817, 0x1b10181e, 0x1f1d1629, 0x162a103c, 0x0f340e3c, 0x034ef07b,
0x15351638, 0x193d1521, 0x1332113d, 0xfd4ef84a, 0xf748f648, 0xee4bf447,
0xf53ffb46, 0xef4bf248, 0xf043f835, 0xf23bf734, 0xf54409fe, 0x1ef61ffc,
0x21ff2107, 0x1f0c2517, 0x1f261440, 0xf747f925, 0xf82cf531, 0xf638f43b,
0xf83ff743, 0xfa44f64f, 0xfd4ef84a, 0xf748f648, 0xee4bf447, 0xf53ffb46,
0xef4bf248, 0xf043f835, 0xf23bf734, 0xf54409fe, 0x1ef61ffc, 0x21ff2107,
0x1f0c2517, 0x1f261440
};

View File

@ -0,0 +1,961 @@
/*------------------------------------------------------------------------------
-- --
-- This software is confidential and proprietary and may be used --
-- only as expressly authorized by a licensing agreement from --
-- --
-- Hantro Products Oy. --
-- --
-- (C) COPYRIGHT 2006 HANTRO PRODUCTS OY --
-- ALL RIGHTS RESERVED --
-- --
-- The entire notice above must be reproduced --
-- on all copies and should not be removed. --
-- --
--------------------------------------------------------------------------------
--
-- Abstract : Context Adaptive Variable Lengtch Code (CAVLC) decoding
--
--------------------------------------------------------------------------------
--
-- Version control information, please leave untouched.
--
-- $RCSfile: h264hwd_cavlc.c,v $
-- $Date: 2008/07/08 11:23:19 $
-- $Revision: 1.2 $
--
------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------
1. Include headers
------------------------------------------------------------------------------*/
#include "h264hwd_cavlc.h"
#include "h264hwd_util.h"
#include "dwl.h"
/*------------------------------------------------------------------------------
2. External compiler flags
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
3. Module defines
------------------------------------------------------------------------------*/
/* Following descriptions use term "information field" to represent combination
* of certain decoded symbol value and the length of the corresponding variable
* length code word. For example, total_zeros information field consists of
* 4 bits symbol value (bits [4,7]) along with four bits to represent length
* of the VLC code word (bits [0,3]) */
/* macro to obtain length of the coeff token information field, bits [0,4] */
#define LENGTH_TC(vlc) ((vlc) & 0x1F)
/* macro to obtain length of the other information fields, bits [0,3] */
#define LENGTH(vlc) ((vlc) & 0xF)
/* macro to obtain code word from the information fields, bits [4,7] */
#define INFO(vlc) (((vlc) >> 4) & 0xF) /* 4 MSB bits contain information */
/* macro to obtain trailing ones from the coeff token information word,
* bits [5,10] */
#define TRAILING_ONES(coeffToken) ((coeffToken>>5) & 0x3F)
/* macro to obtain total coeff from the coeff token information word,
* bits [11,15] */
#define TOTAL_COEFF(coeffToken) (((coeffToken) >> 11) & 0x1F)
#define VLC_NOT_FOUND 0xFFFFFFFEU
/* VLC tables for coeff_token. Because of long codes (max. 16 bits) some of the
* tables have been splitted into multiple separate tables. Each array/table
* element has the following structure:
* [5 bits for tot.coeff.] [6 bits for tr.ones] [5 bits for VLC length]
* If there is a 0x0000 value, it means that there is not corresponding VLC
* codeword for that index. */
/* VLC lengths up to 6 bits, 0 <= nC < 2 */
static const u16 coeffToken0_0[32] = {
0x0000, 0x0000, 0x0000, 0x2066, 0x1026, 0x0806, 0x1865, 0x1865,
0x1043, 0x1043, 0x1043, 0x1043, 0x1043, 0x1043, 0x1043, 0x1043,
0x0822, 0x0822, 0x0822, 0x0822, 0x0822, 0x0822, 0x0822, 0x0822,
0x0822, 0x0822, 0x0822, 0x0822, 0x0822, 0x0822, 0x0822, 0x0822
};
/* VLC lengths up to 10 bits, 0 <= nC < 2 */
static const u16 coeffToken0_1[48] = {
0x0000, 0x0000, 0x0000, 0x0000, 0x406a, 0x304a, 0x282a, 0x200a,
0x3869, 0x3869, 0x2849, 0x2849, 0x2029, 0x2029, 0x1809, 0x1809,
0x3068, 0x3068, 0x3068, 0x3068, 0x2048, 0x2048, 0x2048, 0x2048,
0x1828, 0x1828, 0x1828, 0x1828, 0x1008, 0x1008, 0x1008, 0x1008,
0x2867, 0x2867, 0x2867, 0x2867, 0x2867, 0x2867, 0x2867, 0x2867,
0x1847, 0x1847, 0x1847, 0x1847, 0x1847, 0x1847, 0x1847, 0x1847
};
/* VLC lengths up to 14 bits, 0 <= nC < 2 */
static const u16 coeffToken0_2[56] = {
0x606e, 0x584e, 0x502e, 0x500e, 0x586e, 0x504e, 0x482e, 0x480e,
0x400d, 0x400d, 0x484d, 0x484d, 0x402d, 0x402d, 0x380d, 0x380d,
0x506d, 0x506d, 0x404d, 0x404d, 0x382d, 0x382d, 0x300d, 0x300d,
0x486b, 0x486b, 0x486b, 0x486b, 0x486b, 0x486b, 0x486b, 0x486b,
0x384b, 0x384b, 0x384b, 0x384b, 0x384b, 0x384b, 0x384b, 0x384b,
0x302b, 0x302b, 0x302b, 0x302b, 0x302b, 0x302b, 0x302b, 0x302b,
0x280b, 0x280b, 0x280b, 0x280b, 0x280b, 0x280b, 0x280b, 0x280b
};
/* VLC lengths up to 16 bits, 0 <= nC < 2 */
static const u16 coeffToken0_3[32] = {
0x0000, 0x0000, 0x682f, 0x682f, 0x8010, 0x8050, 0x8030, 0x7810,
0x8070, 0x7850, 0x7830, 0x7010, 0x7870, 0x7050, 0x7030, 0x6810,
0x706f, 0x706f, 0x684f, 0x684f, 0x602f, 0x602f, 0x600f, 0x600f,
0x686f, 0x686f, 0x604f, 0x604f, 0x582f, 0x582f, 0x580f, 0x580f
};
/* VLC lengths up to 6 bits, 2 <= nC < 4 */
static const u16 coeffToken2_0[32] = {
0x0000, 0x0000, 0x0000, 0x0000, 0x3866, 0x2046, 0x2026, 0x1006,
0x3066, 0x1846, 0x1826, 0x0806, 0x2865, 0x2865, 0x1025, 0x1025,
0x2064, 0x2064, 0x2064, 0x2064, 0x1864, 0x1864, 0x1864, 0x1864,
0x1043, 0x1043, 0x1043, 0x1043, 0x1043, 0x1043, 0x1043, 0x1043
};
/* VLC lengths up to 9 bits, 2 <= nC < 4 */
static const u16 coeffToken2_1[32] = {
0x0000, 0x0000, 0x0000, 0x0000, 0x4869, 0x3849, 0x3829, 0x3009,
0x2808, 0x2808, 0x3048, 0x3048, 0x3028, 0x3028, 0x2008, 0x2008,
0x4067, 0x4067, 0x4067, 0x4067, 0x2847, 0x2847, 0x2847, 0x2847,
0x2827, 0x2827, 0x2827, 0x2827, 0x1807, 0x1807, 0x1807, 0x1807
};
/* VLC lengths up to 14 bits, 2 <= nC < 4 */
static const u16 coeffToken2_2[128] = {
0x0000, 0x0000, 0x786d, 0x786d, 0x806e, 0x804e, 0x802e, 0x800e,
0x782e, 0x780e, 0x784e, 0x702e, 0x704d, 0x704d, 0x700d, 0x700d,
0x706d, 0x706d, 0x684d, 0x684d, 0x682d, 0x682d, 0x680d, 0x680d,
0x686d, 0x686d, 0x604d, 0x604d, 0x602d, 0x602d, 0x600d, 0x600d,
0x580c, 0x580c, 0x580c, 0x580c, 0x584c, 0x584c, 0x584c, 0x584c,
0x582c, 0x582c, 0x582c, 0x582c, 0x500c, 0x500c, 0x500c, 0x500c,
0x606c, 0x606c, 0x606c, 0x606c, 0x504c, 0x504c, 0x504c, 0x504c,
0x502c, 0x502c, 0x502c, 0x502c, 0x480c, 0x480c, 0x480c, 0x480c,
0x586b, 0x586b, 0x586b, 0x586b, 0x586b, 0x586b, 0x586b, 0x586b,
0x484b, 0x484b, 0x484b, 0x484b, 0x484b, 0x484b, 0x484b, 0x484b,
0x482b, 0x482b, 0x482b, 0x482b, 0x482b, 0x482b, 0x482b, 0x482b,
0x400b, 0x400b, 0x400b, 0x400b, 0x400b, 0x400b, 0x400b, 0x400b,
0x506b, 0x506b, 0x506b, 0x506b, 0x506b, 0x506b, 0x506b, 0x506b,
0x404b, 0x404b, 0x404b, 0x404b, 0x404b, 0x404b, 0x404b, 0x404b,
0x402b, 0x402b, 0x402b, 0x402b, 0x402b, 0x402b, 0x402b, 0x402b,
0x380b, 0x380b, 0x380b, 0x380b, 0x380b, 0x380b, 0x380b, 0x380b
};
/* VLC lengths up to 6 bits, 4 <= nC < 8 */
static const u16 coeffToken4_0[64] = {
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x1806, 0x3846, 0x3826, 0x1006, 0x4866, 0x3046, 0x3026, 0x0806,
0x2825, 0x2825, 0x2845, 0x2845, 0x2025, 0x2025, 0x2045, 0x2045,
0x1825, 0x1825, 0x4065, 0x4065, 0x1845, 0x1845, 0x1025, 0x1025,
0x3864, 0x3864, 0x3864, 0x3864, 0x3064, 0x3064, 0x3064, 0x3064,
0x2864, 0x2864, 0x2864, 0x2864, 0x2064, 0x2064, 0x2064, 0x2064,
0x1864, 0x1864, 0x1864, 0x1864, 0x1044, 0x1044, 0x1044, 0x1044,
0x0824, 0x0824, 0x0824, 0x0824, 0x0004, 0x0004, 0x0004, 0x0004
};
/* VLC lengths up to 10 bits, 4 <= nC < 8 */
static const u16 coeffToken4_1[128] = {
0x0000, 0x800a, 0x806a, 0x804a, 0x802a, 0x780a, 0x786a, 0x784a,
0x782a, 0x700a, 0x706a, 0x704a, 0x702a, 0x680a, 0x6829, 0x6829,
0x6009, 0x6009, 0x6849, 0x6849, 0x6029, 0x6029, 0x5809, 0x5809,
0x6869, 0x6869, 0x6049, 0x6049, 0x5829, 0x5829, 0x5009, 0x5009,
0x6068, 0x6068, 0x6068, 0x6068, 0x5848, 0x5848, 0x5848, 0x5848,
0x5028, 0x5028, 0x5028, 0x5028, 0x4808, 0x4808, 0x4808, 0x4808,
0x5868, 0x5868, 0x5868, 0x5868, 0x5048, 0x5048, 0x5048, 0x5048,
0x4828, 0x4828, 0x4828, 0x4828, 0x4008, 0x4008, 0x4008, 0x4008,
0x3807, 0x3807, 0x3807, 0x3807, 0x3807, 0x3807, 0x3807, 0x3807,
0x3007, 0x3007, 0x3007, 0x3007, 0x3007, 0x3007, 0x3007, 0x3007,
0x4847, 0x4847, 0x4847, 0x4847, 0x4847, 0x4847, 0x4847, 0x4847,
0x2807, 0x2807, 0x2807, 0x2807, 0x2807, 0x2807, 0x2807, 0x2807,
0x5067, 0x5067, 0x5067, 0x5067, 0x5067, 0x5067, 0x5067, 0x5067,
0x4047, 0x4047, 0x4047, 0x4047, 0x4047, 0x4047, 0x4047, 0x4047,
0x4027, 0x4027, 0x4027, 0x4027, 0x4027, 0x4027, 0x4027, 0x4027,
0x2007, 0x2007, 0x2007, 0x2007, 0x2007, 0x2007, 0x2007, 0x2007
};
/* fixed 6 bit length VLC, nC <= 8 */
static const u16 coeffToken8[64] = {
0x0806, 0x0826, 0x0000, 0x0006, 0x1006, 0x1026, 0x1046, 0x0000,
0x1806, 0x1826, 0x1846, 0x1866, 0x2006, 0x2026, 0x2046, 0x2066,
0x2806, 0x2826, 0x2846, 0x2866, 0x3006, 0x3026, 0x3046, 0x3066,
0x3806, 0x3826, 0x3846, 0x3866, 0x4006, 0x4026, 0x4046, 0x4066,
0x4806, 0x4826, 0x4846, 0x4866, 0x5006, 0x5026, 0x5046, 0x5066,
0x5806, 0x5826, 0x5846, 0x5866, 0x6006, 0x6026, 0x6046, 0x6066,
0x6806, 0x6826, 0x6846, 0x6866, 0x7006, 0x7026, 0x7046, 0x7066,
0x7806, 0x7826, 0x7846, 0x7866, 0x8006, 0x8026, 0x8046, 0x8066
};
/* VLC lengths up to 3 bits, nC == -1 */
static const u16 coeffTokenMinus1_0[8] = {
0x0000, 0x1043, 0x0002, 0x0002, 0x0821, 0x0821, 0x0821, 0x0821
};
/* VLC lengths up to 8 bits, nC == -1 */
static const u16 coeffTokenMinus1_1[32] = {
0x2067, 0x2067, 0x2048, 0x2028, 0x1847, 0x1847, 0x1827, 0x1827,
0x2006, 0x2006, 0x2006, 0x2006, 0x1806, 0x1806, 0x1806, 0x1806,
0x1006, 0x1006, 0x1006, 0x1006, 0x1866, 0x1866, 0x1866, 0x1866,
0x1026, 0x1026, 0x1026, 0x1026, 0x0806, 0x0806, 0x0806, 0x0806
};
/* VLC tables for total_zeros. One table containing longer code, totalZeros_1,
* has been broken into two separate tables. Table elements have the
* following structure:
* [4 bits for info] [4 bits for VLC length] */
/* VLC lengths up to 5 bits */
static const u8 totalZeros_1_0[32] = {
0x00, 0x00, 0x65, 0x55, 0x44, 0x44, 0x34, 0x34,
0x23, 0x23, 0x23, 0x23, 0x13, 0x13, 0x13, 0x13,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01
};
/* VLC lengths up to 9 bits */
static const u8 totalZeros_1_1[32] = {
0x00, 0xf9, 0xe9, 0xd9, 0xc8, 0xc8, 0xb8, 0xb8,
0xa7, 0xa7, 0xa7, 0xa7, 0x97, 0x97, 0x97, 0x97,
0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76
};
static const u8 totalZeros_2[64] = {
0xe6, 0xd6, 0xc6, 0xb6, 0xa5, 0xa5, 0x95, 0x95,
0x84, 0x84, 0x84, 0x84, 0x74, 0x74, 0x74, 0x74,
0x64, 0x64, 0x64, 0x64, 0x54, 0x54, 0x54, 0x54,
0x43, 0x43, 0x43, 0x43, 0x43, 0x43, 0x43, 0x43,
0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23,
0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13,
0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03
};
static const u8 totalZeros_3[64] = {
0xd6, 0xb6, 0xc5, 0xc5, 0xa5, 0xa5, 0x95, 0x95,
0x84, 0x84, 0x84, 0x84, 0x54, 0x54, 0x54, 0x54,
0x44, 0x44, 0x44, 0x44, 0x04, 0x04, 0x04, 0x04,
0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73,
0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23,
0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13
};
static const u8 totalZeros_4[32] = {
0xc5, 0xb5, 0xa5, 0x05, 0x94, 0x94, 0x74, 0x74,
0x34, 0x34, 0x24, 0x24, 0x83, 0x83, 0x83, 0x83,
0x63, 0x63, 0x63, 0x63, 0x53, 0x53, 0x53, 0x53,
0x43, 0x43, 0x43, 0x43, 0x13, 0x13, 0x13, 0x13
};
static const u8 totalZeros_5[32] = {
0xb5, 0x95, 0xa4, 0xa4, 0x84, 0x84, 0x24, 0x24,
0x14, 0x14, 0x04, 0x04, 0x73, 0x73, 0x73, 0x73,
0x63, 0x63, 0x63, 0x63, 0x53, 0x53, 0x53, 0x53,
0x43, 0x43, 0x43, 0x43, 0x33, 0x33, 0x33, 0x33
};
static const u8 totalZeros_6[64] = {
0xa6, 0x06, 0x15, 0x15, 0x84, 0x84, 0x84, 0x84,
0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93,
0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73,
0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53,
0x43, 0x43, 0x43, 0x43, 0x43, 0x43, 0x43, 0x43,
0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23
};
static const u8 totalZeros_7[64] = {
0x96, 0x06, 0x15, 0x15, 0x74, 0x74, 0x74, 0x74,
0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
0x43, 0x43, 0x43, 0x43, 0x43, 0x43, 0x43, 0x43,
0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23,
0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52,
0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52
};
static const u8 totalZeros_8[64] = {
0x86, 0x06, 0x25, 0x25, 0x14, 0x14, 0x14, 0x14,
0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73,
0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52,
0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52,
0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42
};
static const u8 totalZeros_9[64] = {
0x16, 0x06, 0x75, 0x75, 0x24, 0x24, 0x24, 0x24,
0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53,
0x62, 0x62, 0x62, 0x62, 0x62, 0x62, 0x62, 0x62,
0x62, 0x62, 0x62, 0x62, 0x62, 0x62, 0x62, 0x62,
0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32,
0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32
};
static const u8 totalZeros_10[32] = {
0x15, 0x05, 0x64, 0x64, 0x23, 0x23, 0x23, 0x23,
0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52,
0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32
};
static const u8 totalZeros_11[16] = {
0x04, 0x14, 0x23, 0x23, 0x33, 0x33, 0x53, 0x53,
0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41
};
static const u8 totalZeros_12[16] = {
0x04, 0x14, 0x43, 0x43, 0x22, 0x22, 0x22, 0x22,
0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31
};
static const u8 totalZeros_13[8] =
{ 0x03, 0x13, 0x32, 0x32, 0x21, 0x21, 0x21, 0x21 };
static const u8 totalZeros_14[4] = { 0x02, 0x12, 0x21, 0x21 };
/* VLC tables for run_before. Table elements have the following structure:
* [4 bits for info] [4bits for VLC length]
*/
static const u8 runBefore_6[8] =
{ 0x13, 0x23, 0x43, 0x33, 0x63, 0x53, 0x02, 0x02 };
static const u8 runBefore_5[8] =
{ 0x53, 0x43, 0x33, 0x23, 0x12, 0x12, 0x02, 0x02 };
static const u8 runBefore_4[8] =
{ 0x43, 0x33, 0x22, 0x22, 0x12, 0x12, 0x02, 0x02 };
static const u8 runBefore_3[4] = { 0x32, 0x22, 0x12, 0x02 };
static const u8 runBefore_2[4] = { 0x22, 0x12, 0x01, 0x01 };
static const u8 runBefore_1[2] = { 0x11, 0x01 };
/* following four macros are used to handle stream buffer "cache" in the CAVLC
* decoding function */
/* macro to initialize stream buffer cache, fills the buffer (32 bits) */
#define BUFFER_INIT(value, bits) \
{ \
bits = 32; \
value = h264bsdShowBits(pStrmData,32); \
}
/* macro to read numBits bits from the buffer, bits will be written to
* outVal. Refills the buffer if not enough bits left */
#define BUFFER_SHOW(value, bits, outVal, numBits) \
{ \
if (bits < (numBits)) \
{ \
if(h264bsdFlushBits(pStrmData,32-bits) == END_OF_STREAM) \
return(~0); \
value = h264bsdShowBits(pStrmData,32); \
bits = 32; \
} \
(outVal) = value >> (32 - (numBits)); \
}
/* macro to flush numBits bits from the buffer */
#define BUFFER_FLUSH(value, bits, numBits) \
{ \
value <<= (numBits); \
bits -= (numBits); \
}
/* macro to read and flush numBits bits from the buffer, bits will be written
* to outVal. Refills the buffer if not enough bits left */
#define BUFFER_GET(value, bits, outVal, numBits) \
{ \
if (bits < (numBits)) \
{ \
if(h264bsdFlushBits(pStrmData,32-bits) == END_OF_STREAM) \
return(~0); \
value = h264bsdShowBits(pStrmData,32); \
bits = 32; \
} \
(outVal) = value >> (32 - (numBits)); \
value <<= (numBits); \
bits -= (numBits); \
}
/*------------------------------------------------------------------------------
4. Local function prototypes
------------------------------------------------------------------------------*/
static u32 DecodeCoeffToken(u32 bits, u32 nc);
static u32 DecodeLevelPrefix(u32 bits);
static u32 DecodeTotalZeros(u32 bits, u32 totalCoeff, u32 isChromaDC);
static u32 DecodeRunBefore(u32 bits, u32 zerosLeft);
/*------------------------------------------------------------------------------
Function: DecodeCoeffToken
Functional description:
Function to decode coeff_token information field from the stream.
Inputs:
u32 bits next 16 stream bits
u32 nc nC, see standard for details
Outputs:
u32 information field (11 bits for value, 5 bits for length)
------------------------------------------------------------------------------*/
u32 DecodeCoeffToken(u32 bits, u32 nc)
{
/* Variables */
u32 value;
/* Code */
/* standard defines that nc for decoding of chroma dc coefficients is -1,
* represented by u32 here -> -1 maps to 2^32 - 1 */
ASSERT(nc <= 16 || nc == (u32) (-1));
if(nc < 2)
{
if(bits >= 0x8000)
{
value = 0x0001;
}
else if(bits >= 0x0C00)
value = coeffToken0_0[bits >> 10];
else if(bits >= 0x0100)
value = coeffToken0_1[bits >> 6];
else if(bits >= 0x0020)
value = coeffToken0_2[(bits >> 2) - 8];
else
value = coeffToken0_3[bits];
}
else if(nc < 4)
{
if(bits >= 0x8000)
{
value = bits & 0x4000 ? 0x0002 : 0x0822;
}
else if(bits >= 0x1000)
value = coeffToken2_0[bits >> 10];
else if(bits >= 0x0200)
value = coeffToken2_1[bits >> 7];
else
value = coeffToken2_2[bits >> 2];
}
else if(nc < 8)
{
value = coeffToken4_0[bits >> 10];
if(!value)
value = coeffToken4_1[bits >> 6];
}
else if(nc <= 16)
{
value = coeffToken8[bits >> 10];
}
else
{
value = coeffTokenMinus1_0[bits >> 13];
if(!value)
value = coeffTokenMinus1_1[bits >> 8];
}
return (value);
}
/*------------------------------------------------------------------------------
Function: DecodeLevelPrefix
Functional description:
Function to decode level_prefix information field from the stream
Inputs:
u32 bits next 16 stream bits
Outputs:
u32 level_prefix information field or VLC_NOT_FOUND
------------------------------------------------------------------------------*/
u32 DecodeLevelPrefix(u32 bits)
{
/* Variables */
u32 numZeros;
/* Code */
if(bits >= 0x8000)
numZeros = 0;
else if(bits >= 0x4000)
numZeros = 1;
else if(bits >= 0x2000)
numZeros = 2;
else if(bits >= 0x1000)
numZeros = 3;
else if(bits >= 0x0800)
numZeros = 4;
else if(bits >= 0x0400)
numZeros = 5;
else if(bits >= 0x0200)
numZeros = 6;
else if(bits >= 0x0100)
numZeros = 7;
else if(bits >= 0x0080)
numZeros = 8;
else if(bits >= 0x0040)
numZeros = 9;
else if(bits >= 0x0020)
numZeros = 10;
else if(bits >= 0x0010)
numZeros = 11;
else if(bits >= 0x0008)
numZeros = 12;
else if(bits >= 0x0004)
numZeros = 13;
else if(bits >= 0x0002)
numZeros = 14;
else if(bits >= 0x0001)
numZeros = 15;
else /* more than 15 zeros encountered which is an error */
return (VLC_NOT_FOUND);
return (numZeros);
}
/*------------------------------------------------------------------------------
Function: DecodeTotalZeros
Functional description:
Function to decode total_zeros information field from the stream
Inputs:
u32 bits next 9 stream bits
u32 totalCoeff total number of coefficients for the block
being decoded
u32 isChromaDC flag to indicate chroma DC block
Outputs:
u32 information field (4 bits value, 4 bits length)
------------------------------------------------------------------------------*/
u32 DecodeTotalZeros(u32 bits, u32 totalCoeff, u32 isChromaDC)
{
/* Variables */
u32 value = 0x0;
/* Code */
ASSERT(totalCoeff);
if(!isChromaDC)
{
ASSERT(totalCoeff < 16);
switch (totalCoeff)
{
case 1:
value = totalZeros_1_0[bits >> 4];
if(!value)
value = totalZeros_1_1[bits];
break;
case 2:
value = totalZeros_2[bits >> 3];
break;
case 3:
value = totalZeros_3[bits >> 3];
break;
case 4:
value = totalZeros_4[bits >> 4];
break;
case 5:
value = totalZeros_5[bits >> 4];
break;
case 6:
value = totalZeros_6[bits >> 3];
break;
case 7:
value = totalZeros_7[bits >> 3];
break;
case 8:
value = totalZeros_8[bits >> 3];
break;
case 9:
value = totalZeros_9[bits >> 3];
break;
case 10:
value = totalZeros_10[bits >> 4];
break;
case 11:
value = totalZeros_11[bits >> 5];
break;
case 12:
value = totalZeros_12[bits >> 5];
break;
case 13:
value = totalZeros_13[bits >> 6];
break;
case 14:
value = totalZeros_14[bits >> 7];
break;
default: /* case 15 */
value = (bits >> 8) ? 0x11 : 0x01;
break;
}
}
else
{
ASSERT(totalCoeff < 4);
bits >>= 6;
if(bits > 3)
value = 0x01;
else
{
if(totalCoeff == 3)
value = 0x11;
else if(bits > 1)
{
value = 0x12;
}
else if(totalCoeff == 2)
value = 0x22;
else if(bits)
value = 0x23;
else
value = 0x33;
}
}
return (value);
}
/*------------------------------------------------------------------------------
Function: DecodeRunBefore
Functional description:
Function to decode run_before information field from the stream
Inputs:
u32 bits next 11 stream bits
u32 zerosLeft number of zeros left for the current block
Outputs:
u32 information field (4 bits value, 4 bits length)
------------------------------------------------------------------------------*/
u32 DecodeRunBefore(u32 bits, u32 zerosLeft)
{
/* Variables */
u32 value = 0x0;
/* Code */
switch (zerosLeft)
{
case 1:
value = runBefore_1[bits >> 10];
break;
case 2:
value = runBefore_2[bits >> 9];
break;
case 3:
value = runBefore_3[bits >> 9];
break;
case 4:
value = runBefore_4[bits >> 8];
break;
case 5:
value = runBefore_5[bits >> 8];
break;
case 6:
value = runBefore_6[bits >> 8];
break;
default:
if(bits >= 0x100)
value = ((7 - (bits >> 8)) << 4) + 0x3;
else if(bits >= 0x80)
value = 0x74;
else if(bits >= 0x40)
value = 0x85;
else if(bits >= 0x20)
value = 0x96;
else if(bits >= 0x10)
value = 0xa7;
else if(bits >= 0x8)
value = 0xb8;
else if(bits >= 0x4)
value = 0xc9;
else if(bits >= 0x2)
value = 0xdA;
else if(bits)
value = 0xeB;
if(INFO(value) > zerosLeft)
value = 0;
break;
}
return (value);
}
/*------------------------------------------------------------------------------
Function: DecodeResidualBlockCavlc
Functional description:
Function to decode one CAVLC coded block. This corresponds to
syntax elements residual_block_cavlc() in the standard.
Inputs:
pStrmData pointer to stream data structure
nc nC value
maxNumCoeff maximum number of residual coefficients
Outputs:
coeffLevel stores decoded coefficient levels
Returns:
totalCoeff numebr of coeffs decoded
(~0) end of stream or error in stream
------------------------------------------------------------------------------*/
u32 h264bsdDecodeResidualBlockCavlc(strmData_t * pStrmData,
u16 * coeffLevel, i32 nc, u32 maxNumCoeff)
{
/* Variables */
u32 i, tmp, totalCoeff, trailingOnes, suffixLength, levelPrefix;
u32 levelSuffix, zerosLeft, bit;
i32 level[16];
u32 run[16];
/* stream "cache" */
u32 bufferValue;
u32 bufferBits;
/* Code */
ASSERT(pStrmData);
ASSERT(coeffLevel);
ASSERT(nc > -2);
ASSERT(maxNumCoeff == 4 || maxNumCoeff == 15 || maxNumCoeff == 16);
ASSERT(VLC_NOT_FOUND != END_OF_STREAM);
/* assume that coeffLevel array has been "cleaned" by caller */
BUFFER_INIT(bufferValue, bufferBits);
/*lint -e774 disable lint warning on always false comparison */
BUFFER_SHOW(bufferValue, bufferBits, bit, 16);
/*lint +e774 */
tmp = DecodeCoeffToken(bit, (u32) nc);
if(!tmp)
return (~0);
BUFFER_FLUSH(bufferValue, bufferBits, LENGTH_TC(tmp));
totalCoeff = TOTAL_COEFF(tmp);
if(totalCoeff > maxNumCoeff)
return (~0);
trailingOnes = TRAILING_ONES(tmp);
if(totalCoeff != 0)
{
i = 0;
/* nonzero coefficients: +/- 1 */
if(trailingOnes)
{
BUFFER_GET(bufferValue, bufferBits, bit, trailingOnes);
tmp = 1 << (trailingOnes - 1);
for(; tmp; i++)
{
level[i] = bit & tmp ? -1 : 1;
tmp >>= 1;
}
}
/* other levels */
if(totalCoeff > 10 && trailingOnes < 3)
suffixLength = 1;
else
suffixLength = 0;
for(; i < totalCoeff; i++)
{
BUFFER_SHOW(bufferValue, bufferBits, bit, 16);
levelPrefix = DecodeLevelPrefix(bit);
if(levelPrefix == VLC_NOT_FOUND)
return (~0);
BUFFER_FLUSH(bufferValue, bufferBits, levelPrefix + 1);
if(levelPrefix < 14)
tmp = suffixLength;
else if(levelPrefix == 14)
{
tmp = suffixLength ? suffixLength : 4;
}
else
{
/* setting suffixLength to 1 here corresponds to adding 15
* to levelCode value if levelPrefix == 15 and
* suffixLength == 0 */
if(!suffixLength)
suffixLength = 1;
tmp = 12;
}
if(suffixLength)
levelPrefix <<= suffixLength;
if(tmp)
{
BUFFER_GET(bufferValue, bufferBits, levelSuffix, tmp);
levelPrefix += levelSuffix;
}
tmp = levelPrefix;
if(i == trailingOnes && trailingOnes < 3)
tmp += 2;
level[i] = (tmp + 2) >> 1;
if(suffixLength == 0)
suffixLength = 1;
if((level[i] > (3 << (suffixLength - 1))) && suffixLength < 6)
suffixLength++;
if(tmp & 0x1)
level[i] = -level[i];
}
/* zero runs */
if(totalCoeff < maxNumCoeff)
{
BUFFER_SHOW(bufferValue, bufferBits, bit, 9);
zerosLeft = DecodeTotalZeros(bit, totalCoeff,
(u32) (maxNumCoeff == 4));
if(!zerosLeft)
return (~0);
BUFFER_FLUSH(bufferValue, bufferBits, LENGTH(zerosLeft));
zerosLeft = INFO(zerosLeft);
}
else
zerosLeft = 0;
if((zerosLeft + totalCoeff) > maxNumCoeff)
{
return (~0);
}
for(i = 0; i < totalCoeff - 1; i++)
{
if(zerosLeft > 0)
{
BUFFER_SHOW(bufferValue, bufferBits, bit, 11);
tmp = DecodeRunBefore(bit, zerosLeft);
if(!tmp)
return (~0);
BUFFER_FLUSH(bufferValue, bufferBits, LENGTH(tmp));
run[i] = INFO(tmp);
zerosLeft -= run[i];
}
else
{
run[i] = 0;
}
}
run[i] = zerosLeft; /* last run */
/*lint -esym(771,level,run) level and run are always initialized */
{
u16 *pTmp = coeffLevel + 2;
u16 bigLevelMask = 0;
for(i = totalCoeff; i--;)
{
bigLevelMask <<= 1;
if(level[i] < 0)
bigLevelMask |= 1;
tmp = (run[i] << 12) | (level[i] & 0x0FFF);
*pTmp++ = (u16) tmp;
}
tmp = totalCoeff << 11;
if(bigLevelMask)
{
tmp |= 1;
bigLevelMask <<= (16 - totalCoeff);
}
*coeffLevel++ = (u16) tmp;
*coeffLevel = bigLevelMask;
}
}
else
{
*coeffLevel = 0; /* no coeffs for this subBlock */
}
if(h264bsdFlushBits(pStrmData, 32 - bufferBits) != HANTRO_OK)
return (~0);
return totalCoeff;
}

View File

@ -0,0 +1,156 @@
/*------------------------------------------------------------------------------
-- --
-- This software is confidential and proprietary and may be used --
-- only as expressly authorized by a licensing agreement from --
-- --
-- Hantro Products Oy. --
-- --
-- (C) COPYRIGHT 2006 HANTRO PRODUCTS OY --
-- ALL RIGHTS RESERVED --
-- --
-- The entire notice above must be reproduced --
-- on all copies and should not be removed. --
-- --
--------------------------------------------------------------------------------
--
-- Abstract : Error concealment
--
--------------------------------------------------------------------------------
--
-- Version control information, please leave untouched.
--
-- $RCSfile: h264hwd_conceal.c,v $
-- $Date: 2008/03/13 12:48:06 $
-- $Revision: 1.1 $
--
------------------------------------------------------------------------------*/
#include "h264hwd_container.h"
#include "h264hwd_conceal.h"
#include "h264hwd_util.h"
#include "h264hwd_dpb.h"
/*------------------------------------------------------------------------------
Function name : h264bsdConceal
Description : Performe error concelament for an erroneous picture
Return type : void
Argument : storage_t *pStorage
Argument : DecAsicBuffers_t * pAsicBuff
Argument : u32 sliceType
------------------------------------------------------------------------------*/
void h264bsdConceal(storage_t * pStorage, DecAsicBuffers_t * pAsicBuff,
u32 sliceType)
{
u32 i, tmp;
i32 refID;
u32 *pAsicCtrl = pAsicBuff->mbCtrl.virtualAddress;
mbStorage_t *pMb = pStorage->mb;
ASSERT(pStorage);
ASSERT(pAsicBuff);
DEBUG_PRINT(("h264bsdConceal: Concealing %s slice\n",
IS_I_SLICE(sliceType) ? "intra" : "inter"));
refID = -1;
/* use reference picture with smallest available index */
if(IS_P_SLICE(sliceType))
{
i = 0;
do
{
refID = h264bsdGetRefPicData(pStorage->dpb, i);
i++;
}
while(i < 16 && refID == -1);
}
i = 0;
/* find first properly decoded macroblock -> start point for concealment */
while(i < pStorage->picSizeInMbs && !pMb[i].decoded)
{
i++;
}
/* whole picture lost -> copy previous or set grey */
if(i == pStorage->picSizeInMbs)
{
DEBUG_PRINT(("h264bsdConceal: whole picture lost\n"));
if(IS_I_SLICE(sliceType) || refID == -1)
{
/* QP = 40 and all residual blocks empty */
/* DC predi. & chroma DC pred. --> grey */
tmp = ((u32) HW_I_16x16 << 29) | (2U << 27) | (40U << 15) | 0x7F;
for(i = pStorage->picSizeInMbs; i > 0; i--)
{
*pAsicCtrl++ = tmp;
*pAsicCtrl++ = 0;
}
pMb->mbType_asic = I_16x16_2_0_0;
}
else
{
/* QP = 40 and all residual blocks empty */
tmp = ((u32) HW_P_SKIP << 29) | (40U << 15) | 0x7F;
for(i = pStorage->picSizeInMbs; i > 0; i--)
{
*pAsicCtrl++ = tmp;
*pAsicCtrl++ = 0;
}
/* inter prediction using zero mv and the newest reference */
pMb->mbType_asic = P_Skip;
pMb->refID[0] = refID;
}
pStorage->numConcealedMbs = pStorage->picSizeInMbs;
return;
}
for(i = 0; i < pStorage->picSizeInMbs; i++, pMb++)
{
/* if mb was not correctly decoded, set parameters for concealment */
if(!pMb->decoded)
{
DEBUG_PRINT(("h264bsdConceal: Concealing mb #%u\n", i));
pStorage->numConcealedMbs++;
/* intra pred. if it is an intra mb or if the newest reference image
* is not available */
if(IS_I_SLICE(sliceType) || refID == -1)
{
/* QP = 40 and all residual blocks empty */
/* DC predi. & chroma DC pred. --> grey */
tmp =
((u32) HW_I_16x16 << 29) | (2U << 27) | (40U << 15) | 0x7F;
*pAsicCtrl++ = tmp;
*pAsicCtrl++ = 0;
pMb->mbType_asic = I_16x16_2_0_0;
}
else
{
DEBUG_PRINT(("h264bsdConceal: NOT I slice conceal \n"));
/* QP = 40 and all residual blocks empty */
tmp = ((u32) HW_P_SKIP << 29) | (40U << 15) | 0x7F;
*pAsicCtrl++ = tmp;
*pAsicCtrl++ = 0;
/* inter prediction using zero mv and the newest reference */
pMb->mbType_asic = P_Skip;
pMb->refID[0] = refID;
}
}
else
pAsicCtrl += 2;
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,329 @@
/*------------------------------------------------------------------------------
-- --
-- This software is confidential and proprietary and may be used --
-- only as expressly authorized by a licensing agreement from --
-- --
-- Hantro Products Oy. --
-- --
-- (C) COPYRIGHT 2006 HANTRO PRODUCTS OY --
-- ALL RIGHTS RESERVED --
-- --
-- The entire notice above must be reproduced --
-- on all copies and should not be removed. --
-- --
--------------------------------------------------------------------------------
--
-- Abstract : Inter prediction. MV and referece frame update
--
--------------------------------------------------------------------------------
--
-- Version control information, please leave untouched.
--
-- $RCSfile: h264hwd_inter_prediction.c,v $
-- $Date: 2008/03/13 12:48:06 $
-- $Revision: 1.1 $
--
------------------------------------------------------------------------------*/
#include "h264hwd_container.h"
#include "h264hwd_util.h"
#include "h264hwd_macroblock_layer.h"
#include "h264hwd_neighbour.h"
#include "h264hwd_exports.h"
/*------------------------------------------------------------------------------
4. Local function prototypes
------------------------------------------------------------------------------*/
static u32 MvPredictionSkip(mbStorage_t * pMb, dpbStorage_t * dpb);
static u32 MvPrediction16x16(mbStorage_t * pMb, dpbStorage_t * dpb);
static u32 MvPrediction16x8(mbStorage_t * pMb, dpbStorage_t * dpb);
static u32 MvPrediction8x16(mbStorage_t * pMb, dpbStorage_t * dpb);
static u32 MvPrediction8x8(mbStorage_t * pMb, subMbPred_t * subMbPred,
dpbStorage_t * dpb);
static u32 GetInterNeighbour(u32 sliceId, /*@null@ */ mbStorage_t * nMb);
/*------------------------------------------------------------------------------
Function name : PrepareInterPrediction
Description : Processes one inter macroblock. Writes MB control data
Return type : u32 - 0 for success or a negative error code
Argument : mbStorage_t * pMb - pointer to macroblock specific information
Argument : macroblockLayer_t * pMbLayer - macroblock layer data
Argument : dpbStorage_t * dpb - DPB data
Argument : DecAsicBuffers_t * pAsicBuff - SW/HW interface
------------------------------------------------------------------------------*/
u32 PrepareInterPrediction(mbStorage_t * pMb, macroblockLayer_t * pMbLayer,
dpbStorage_t * dpb, DecAsicBuffers_t * pAsicBuff)
{
ASSERT(pMb);
ASSERT(h264bsdMbPartPredMode(pMb->mbType) == PRED_MODE_INTER);
ASSERT(pMbLayer);
/* if decoded flag > 1 -> mb has already been successfully decoded and
* written to output -> do not write again */
if(pMb->decoded > 1)
goto end;
switch (pMb->mbType)
{
case P_Skip:
if(MvPredictionSkip(pMb, dpb) != HANTRO_OK)
return (HANTRO_NOK);
break;
case P_L0_16x16:
if(MvPrediction16x16(pMb, dpb) != HANTRO_OK)
return (HANTRO_NOK);
break;
case P_L0_L0_16x8:
if(MvPrediction16x8(pMb, dpb) != HANTRO_OK)
return (HANTRO_NOK);
break;
case P_L0_L0_8x16:
if(MvPrediction8x16(pMb, dpb) != HANTRO_OK)
return (HANTRO_NOK);
break;
default: /* P_8x8 and P_8x8ref0 */
if(MvPrediction8x8(pMb, &pMbLayer->subMbPred, dpb) != HANTRO_OK)
return (HANTRO_NOK);
break;
}
/* update ASIC MB control field */
{
u32 tmp;
u32 *pAsicCtrl =
pAsicBuff->mbCtrl.virtualAddress +
(pAsicBuff->currentMB * (ASIC_MB_CTRL_BUFFER_SIZE / 4));
switch (pMb->mbType)
{
case P_Skip:
tmp = (u32) HW_P_SKIP << 29;
break;
case P_L0_16x16:
tmp = (u32) HW_P_16x16 << 29;
break;
case P_L0_L0_16x8:
tmp = (u32) HW_P_16x8 << 29;
break;
case P_L0_L0_8x16:
tmp = (u32) HW_P_8x16 << 29;
break;
default: /* P_8x8 and P_8x8ref0 */
tmp = (u32) HW_P_8x8 << 29;
tmp |= pMbLayer->subMbPred.subMbType[0] << 27;
tmp |= pMbLayer->subMbPred.subMbType[1] << 25;
tmp |= pMbLayer->subMbPred.subMbType[2] << 23;
tmp |= pMbLayer->subMbPred.subMbType[3] << 21;
break;
}
tmp |= pMb->qpY << 15;
tmp |= (u32) (pMbLayer->filterOffsetA & 0x0F) << 11;
tmp |= (u32) (pMbLayer->filterOffsetB & 0x0F) << 7;
tmp |= pAsicBuff->notCodedMask;
pAsicCtrl[0] = tmp;
{
tmp = GetInterNeighbour(pMb->sliceId, pMb->mbD) << 31;
tmp |= GetInterNeighbour(pMb->sliceId, pMb->mbB) << 30;
tmp |= GetInterNeighbour(pMb->sliceId, pMb->mbC) << 29;
tmp |= GetInterNeighbour(pMb->sliceId, pMb->mbA) << 28;
tmp |= pAsicBuff->rlcWords << 19;
}
tmp |= pMbLayer->disableDeblockingFilterIdc << 17;
pAsicCtrl[1] = tmp;
}
end:
return (HANTRO_OK);
}
/*------------------------------------------------------------------------------
Function: MvPrediction16x16
Functional description:
Motion vector prediction for 16x16 partition mode
------------------------------------------------------------------------------*/
u32 MvPrediction16x16(mbStorage_t * pMb, dpbStorage_t * dpb)
{
u32 refIndex;
i32 tmp;
refIndex = pMb->refIdxL0[0];
tmp = h264bsdGetRefPicData(dpb, refIndex);
if(tmp == -1)
return (HANTRO_NOK);
pMb->refID[0] = (u8) tmp;
return (HANTRO_OK);
}
/*------------------------------------------------------------------------------
Function: MvPredictionSkip
Functional description:
Motion vector prediction skipped macroblock
------------------------------------------------------------------------------*/
u32 MvPredictionSkip(mbStorage_t * pMb, dpbStorage_t * dpb)
{
u32 refIndex = 0;
i32 tmp;
tmp = h264bsdGetRefPicData(dpb, refIndex);
if(tmp == -1)
return (HANTRO_NOK);
pMb->refID[0] = (u8) tmp;
return (HANTRO_OK);
}
/*------------------------------------------------------------------------------
Function: MvPrediction16x8
Functional description:
Motion vector prediction for 16x8 partition mode
------------------------------------------------------------------------------*/
u32 MvPrediction16x8(mbStorage_t * pMb, dpbStorage_t * dpb)
{
u32 refIndex;
i32 tmp;
/* first partition */
refIndex = pMb->refIdxL0[0];
tmp = h264bsdGetRefPicData(dpb, refIndex);
if(tmp == -1)
return (HANTRO_NOK);
pMb->refID[0] = (u8) tmp;
/* second partition */
refIndex = pMb->refIdxL0[1];
tmp = h264bsdGetRefPicData(dpb, refIndex);
if(tmp == -1)
return (HANTRO_NOK);
pMb->refID[1] = (u8) tmp;
return (HANTRO_OK);
}
/*------------------------------------------------------------------------------
Function: MvPrediction8x16
Functional description:
Motion vector prediction for 8x16 partition mode
------------------------------------------------------------------------------*/
u32 MvPrediction8x16(mbStorage_t * pMb, dpbStorage_t * dpb)
{
u32 refIndex;
i32 tmp;
/* first partition */
refIndex = pMb->refIdxL0[0];
tmp = h264bsdGetRefPicData(dpb, refIndex);
if(tmp == -1)
return (HANTRO_NOK);
pMb->refID[0] = (u8) tmp;
/* second partition */
refIndex = pMb->refIdxL0[1];
tmp = h264bsdGetRefPicData(dpb, refIndex);
if(tmp == -1)
return (HANTRO_NOK);
pMb->refID[1] = (u8) tmp;
return (HANTRO_OK);
}
/*------------------------------------------------------------------------------
Function: MvPrediction8x8
Functional description:
Motion vector prediction for 8x8 partition mode
------------------------------------------------------------------------------*/
u32 MvPrediction8x8(mbStorage_t * pMb, subMbPred_t * subMbPred,
dpbStorage_t * dpb)
{
u32 i;
const u8 *refIdxL0 = pMb->refIdxL0;
u8 *refID = pMb->refID;
for(i = 4; i > 0; i--)
{
u32 refIndex;
i32 tmp;
refIndex = *refIdxL0++;
tmp = h264bsdGetRefPicData(dpb, refIndex);
if(tmp == -1)
return (HANTRO_NOK);
*refID++ = (u8) tmp;
}
return (HANTRO_OK);
}
/*------------------------------------------------------------------------------
Function: GetInterNeighbour
Functional description:
Checks if macroblock 'nMb' is part of slice 'sliceId'
------------------------------------------------------------------------------*/
u32 GetInterNeighbour(u32 sliceId, mbStorage_t * nMb)
{
if(nMb && (sliceId == nMb->sliceId))
{
return 1;
}
else
{
return 0;
}
}

View File

@ -0,0 +1,467 @@
/*------------------------------------------------------------------------------
-- --
-- This software is confidential and proprietary and may be used --
-- only as expressly authorized by a licensing agreement from --
-- --
-- Hantro Products Oy. --
-- --
-- (C) COPYRIGHT 2006 HANTRO PRODUCTS OY --
-- ALL RIGHTS RESERVED --
-- --
-- The entire notice above must be reproduced --
-- on all copies and should not be removed. --
-- --
--------------------------------------------------------------------------------
--
-- Abstract : Intra prediction for macroblock
--
--------------------------------------------------------------------------------
--
-- Version control information, please leave untouched.
--
-- $RCSfile: h264hwd_intra_prediction.c,v $
-- $Date: 2008/03/13 12:48:06 $
-- $Revision: 1.1 $
--
------------------------------------------------------------------------------*/
#include "h264hwd_container.h"
#include "h264hwd_util.h"
#include "h264hwd_macroblock_layer.h"
#include "h264hwd_neighbour.h"
#include "h264hwd_exports.h"
static u32 Intra16x16Prediction(mbStorage_t * pMb,
macroblockLayer_t * mbLayer,
u32 constrainedIntraPred,
DecAsicBuffers_t * pAsicBuff);
static u32 Intra4x4Prediction(mbStorage_t * pMb, macroblockLayer_t * mbLayer,
u32 constrainedIntraPred,
DecAsicBuffers_t * pAsicBuff);
static u32 DetermineIntra4x4PredMode(macroblockLayer_t * pMbLayer,
u32 available, neighbour_t * nA,
neighbour_t * nB, u32 index,
/*@null@ */ mbStorage_t * nMbA,
/*@null@ */ mbStorage_t * nMbB);
static u32 GetIntraNeighbour(u32 sliceId, mbStorage_t * nMb);
static u32 CheckIntraChromaPrediction(u32 predMode, u32 availableA,
u32 availableB, u32 availableD);
/*------------------------------------------------------------------------------
Function name : PrepareIntraPrediction
Description :
Return type : u32
Argument : mbStorage_t * pMb
Argument : macroblockLayer_t * mbLayer
Argument : u32 constrainedIntraPred
Argument : DecAsicBuffers_t * pAsicBuff
------------------------------------------------------------------------------*/
u32 PrepareIntraPrediction(mbStorage_t * pMb, macroblockLayer_t * mbLayer,
u32 constrainedIntraPred,
DecAsicBuffers_t * pAsicBuff)
{
u32 tmp;
if(h264bsdMbPartPredMode(pMb->mbType) == PRED_MODE_INTRA4x4)
{
tmp = Intra4x4Prediction(pMb, mbLayer, constrainedIntraPred, pAsicBuff);
if(tmp != HANTRO_OK)
return (tmp);
}
else
{
tmp =
Intra16x16Prediction(pMb, mbLayer, constrainedIntraPred, pAsicBuff);
if(tmp != HANTRO_OK)
return (tmp);
}
return HANTRO_OK;
}
/*------------------------------------------------------------------------------
Function name : Intra16x16Prediction
Description :
Return type : u32
Argument : mbStorage_t * pMb
Argument : macroblockLayer_t * mbLayer
Argument : u32 constrainedIntraPred
Argument : DecAsicBuffers_t * pAsicBuff
------------------------------------------------------------------------------*/
u32 Intra16x16Prediction(mbStorage_t * pMb, macroblockLayer_t * mbLayer,
u32 constrainedIntraPred,
DecAsicBuffers_t * pAsicBuff)
{
u32 mode, tmp;
u32 availableA, availableB, availableD;
ASSERT(h264bsdPredModeIntra16x16(pMb->mbType) < 4);
availableA = h264bsdIsNeighbourAvailable(pMb, pMb->mbA);
if(availableA && constrainedIntraPred &&
(h264bsdMbPartPredMode(pMb->mbA->mbType) == PRED_MODE_INTER))
availableA = HANTRO_FALSE;
availableB = h264bsdIsNeighbourAvailable(pMb, pMb->mbB);
if(availableB && constrainedIntraPred &&
(h264bsdMbPartPredMode(pMb->mbB->mbType) == PRED_MODE_INTER))
availableB = HANTRO_FALSE;
availableD = h264bsdIsNeighbourAvailable(pMb, pMb->mbD);
if(availableD && constrainedIntraPred &&
(h264bsdMbPartPredMode(pMb->mbD->mbType) == PRED_MODE_INTER))
availableD = HANTRO_FALSE;
mode = h264bsdPredModeIntra16x16(pMb->mbType);
switch (mode)
{
case 0: /* Intra_16x16_Vertical */
if(!availableB)
return (HANTRO_NOK);
break;
case 1: /* Intra_16x16_Horizontal */
if(!availableA)
return (HANTRO_NOK);
break;
case 2: /* Intra_16x16_DC */
break;
default: /* case 3: Intra_16x16_Plane */
if(!availableA || !availableB || !availableD)
return (HANTRO_NOK);
break;
}
tmp = CheckIntraChromaPrediction(mbLayer->mbPred.intraChromaPredMode,
availableA, availableB, availableD);
if(tmp != HANTRO_OK)
return (tmp);
if(pMb->decoded > 1)
{
goto end;
}
/* update ASIC MB control field */
{
u32 tmp2;
u32 *pAsicCtrl =
pAsicBuff->mbCtrl.virtualAddress +
(pAsicBuff->currentMB * (ASIC_MB_CTRL_BUFFER_SIZE / 4));
tmp2 = (u32) HW_I_16x16 << 29;
tmp2 |= mode << 27;
tmp2 |= mbLayer->mbPred.intraChromaPredMode << 25;
tmp2 |= ((availableA == HANTRO_TRUE ? 1U : 0U) << 24);
tmp2 |= ((availableB == HANTRO_TRUE ? 1U : 0U) << 23);
tmp2 |= pMb->qpY << 15;
tmp2 |= (u32) (mbLayer->filterOffsetA & 0x0F) << 11;
tmp2 |= (u32) (mbLayer->filterOffsetB & 0x0F) << 7;
tmp2 |= pAsicBuff->notCodedMask;
pAsicCtrl[0] = tmp2;
tmp2 = GetIntraNeighbour(pMb->sliceId, pMb->mbD) << 31;
tmp2 |= GetIntraNeighbour(pMb->sliceId, pMb->mbB) << 30;
tmp2 |= GetIntraNeighbour(pMb->sliceId, pMb->mbC) << 29;
tmp2 |= GetIntraNeighbour(pMb->sliceId, pMb->mbA) << 28;
tmp2 |= pAsicBuff->rlcWords << 19;
tmp2 |= mbLayer->disableDeblockingFilterIdc << 17;
pAsicCtrl[1] = tmp2;
}
end:
return (HANTRO_OK);
}
/*------------------------------------------------------------------------------
Function name : Intra4x4Prediction
Description :
Return type : u32
Argument : mbStorage_t * pMb
Argument : macroblockLayer_t * mbLayer
Argument : u32 constrainedIntraPred
Argument : DecAsicBuffers_t * pAsicBuff
------------------------------------------------------------------------------*/
u32 Intra4x4Prediction(mbStorage_t * pMb, macroblockLayer_t * mbLayer,
u32 constrainedIntraPred, DecAsicBuffers_t * pAsicBuff)
{
u32 block;
u32 mode, tmp;
neighbour_t neighbour, neighbourB;
mbStorage_t *nMb, *nMb2;
u32 availableA, availableB, availableC, availableD;
for(block = 0; block < 16; block++)
{
ASSERT(pMb->intra4x4PredMode[block] < 9);
neighbour = *h264bsdNeighbour4x4BlockA(block);
nMb = h264bsdGetNeighbourMb(pMb, neighbour.mb);
availableA = h264bsdIsNeighbourAvailable(pMb, nMb);
if(availableA && constrainedIntraPred &&
(h264bsdMbPartPredMode(nMb->mbType) == PRED_MODE_INTER))
{
availableA = HANTRO_FALSE;
}
neighbourB = *h264bsdNeighbour4x4BlockB(block);
nMb2 = h264bsdGetNeighbourMb(pMb, neighbourB.mb);
availableB = h264bsdIsNeighbourAvailable(pMb, nMb2);
if(availableB && constrainedIntraPred &&
(h264bsdMbPartPredMode(nMb2->mbType) == PRED_MODE_INTER))
{
availableB = HANTRO_FALSE;
}
mode = DetermineIntra4x4PredMode(mbLayer,
(u32) (availableA && availableB),
&neighbour, &neighbourB, block, nMb,
nMb2);
pMb->intra4x4PredMode[block] = (u8) mode;
if(pMb->decoded == 1)
{
pMb->intra4x4PredMode_asic[block] = (u8) mode;
}
neighbour = *h264bsdNeighbour4x4BlockD(block);
nMb = h264bsdGetNeighbourMb(pMb, neighbour.mb);
availableD = h264bsdIsNeighbourAvailable(pMb, nMb);
if(availableD && constrainedIntraPred &&
(h264bsdMbPartPredMode(nMb->mbType) == PRED_MODE_INTER))
{
availableD = HANTRO_FALSE;
}
switch (mode)
{
case 0: /* Intra_4x4_Vertical */
if(!availableB)
return (HANTRO_NOK);
break;
case 1: /* Intra_4x4_Horizontal */
if(!availableA)
return (HANTRO_NOK);
break;
case 2: /* Intra_4x4_DC */
break;
case 3: /* Intra_4x4_Diagonal_Down_Left */
if(!availableB)
return (HANTRO_NOK);
break;
case 4: /* Intra_4x4_Diagonal_Down_Right */
if(!availableA || !availableB || !availableD)
return (HANTRO_NOK);
break;
case 5: /* Intra_4x4_Vertical_Right */
if(!availableA || !availableB || !availableD)
return (HANTRO_NOK);
break;
case 6: /* Intra_4x4_Horizontal_Down */
if(!availableA || !availableB || !availableD)
return (HANTRO_NOK);
break;
case 7: /* Intra_4x4_Vertical_Left */
if(!availableB)
return (HANTRO_NOK);
break;
default: /* case 8 Intra_4x4_Horizontal_Up */
if(!availableA)
return (HANTRO_NOK);
break;
}
}
availableA = h264bsdIsNeighbourAvailable(pMb, pMb->mbA);
if(availableA && constrainedIntraPred &&
(h264bsdMbPartPredMode(pMb->mbA->mbType) == PRED_MODE_INTER))
availableA = HANTRO_FALSE;
availableB = h264bsdIsNeighbourAvailable(pMb, pMb->mbB);
if(availableB && constrainedIntraPred &&
(h264bsdMbPartPredMode(pMb->mbB->mbType) == PRED_MODE_INTER))
availableB = HANTRO_FALSE;
availableC = h264bsdIsNeighbourAvailable(pMb, pMb->mbC);
if(availableC && constrainedIntraPred &&
(h264bsdMbPartPredMode(pMb->mbC->mbType) == PRED_MODE_INTER))
availableC = HANTRO_FALSE;
availableD = h264bsdIsNeighbourAvailable(pMb, pMb->mbD);
if(availableD && constrainedIntraPred &&
(h264bsdMbPartPredMode(pMb->mbD->mbType) == PRED_MODE_INTER))
availableD = HANTRO_FALSE;
tmp = CheckIntraChromaPrediction(mbLayer->mbPred.intraChromaPredMode,
availableA, availableB, availableD);
if(tmp != HANTRO_OK)
return (tmp);
if(pMb->decoded > 1)
{
goto end;
}
/* update ASIC MB control field */
{
u32 tmp2;
u32 *pAsicCtrl =
pAsicBuff->mbCtrl.virtualAddress +
(pAsicBuff->currentMB * (ASIC_MB_CTRL_BUFFER_SIZE / 4));
tmp2 = (u32) HW_I_4x4 << 29;
tmp2 |= mbLayer->mbPred.intraChromaPredMode << 25;
tmp2 |= ((availableA == HANTRO_TRUE ? 1U : 0U) << 24);
tmp2 |= ((availableB == HANTRO_TRUE ? 1U : 0U) << 23);
tmp2 |= ((availableC == HANTRO_TRUE ? 1U : 0U) << 22);
tmp2 |= pMb->qpY << 15;
tmp2 |= (u32) (mbLayer->filterOffsetA & 0x0F) << 11;
tmp2 |= (u32) (mbLayer->filterOffsetB & 0x0F) << 7;
tmp2 |= pAsicBuff->notCodedMask;
pAsicCtrl[0] = tmp2;
tmp2 = GetIntraNeighbour(pMb->sliceId, pMb->mbD) << 31;
tmp2 |= GetIntraNeighbour(pMb->sliceId, pMb->mbB) << 30;
tmp2 |= GetIntraNeighbour(pMb->sliceId, pMb->mbC) << 29;
tmp2 |= GetIntraNeighbour(pMb->sliceId, pMb->mbA) << 28;
tmp2 |= pAsicBuff->rlcWords << 19;
tmp2 |= mbLayer->disableDeblockingFilterIdc << 17;
pAsicCtrl[1] = tmp2;
}
end:
return (HANTRO_OK);
}
/*------------------------------------------------------------------------------
Function name : DetermineIntra4x4PredMode
Description :
Return type : u32
Argument : macroblockLayer_t * pMbLayer
Argument : u32 available
Argument : neighbour_t * nA
Argument : neighbour_t * nB
Argument : u32 index
Argument : mbStorage_t * nMbA
Argument : mbStorage_t * nMbB
------------------------------------------------------------------------------*/
u32 DetermineIntra4x4PredMode(macroblockLayer_t * pMbLayer,
u32 available, neighbour_t * nA,
neighbour_t * nB, u32 index, mbStorage_t * nMbA,
mbStorage_t * nMbB)
{
u32 mode1, mode2;
mbStorage_t *pMb;
ASSERT(pMbLayer);
if(!available) /* dc only prediction? */
mode1 = 2;
else
{
pMb = nMbA;
if(h264bsdMbPartPredMode(pMb->mbType) == PRED_MODE_INTRA4x4)
{
mode1 = (u32) pMb->intra4x4PredMode[nA->index];
}
else
mode1 = 2;
pMb = nMbB;
if(h264bsdMbPartPredMode(pMb->mbType) == PRED_MODE_INTRA4x4)
{
mode2 = (u32) pMb->intra4x4PredMode[nB->index];
}
else
mode2 = 2;
mode1 = MIN(mode1, mode2);
}
{
mbPred_t *mbPred = &pMbLayer->mbPred;
if(!mbPred->prevIntra4x4PredModeFlag[index])
{
if(mbPred->remIntra4x4PredMode[index] < mode1)
{
mode1 = mbPred->remIntra4x4PredMode[index];
}
else
{
mode1 = mbPred->remIntra4x4PredMode[index] + 1;
}
}
}
return (mode1);
}
/*------------------------------------------------------------------------------
Function: GetIntraNeighbour
Functional description:
Checks if macroblock 'nMb' is part of slice 'sliceId'
------------------------------------------------------------------------------*/
u32 GetIntraNeighbour(u32 sliceId, mbStorage_t * nMb)
{
if(nMb && (sliceId == nMb->sliceId))
{
return 1;
}
else
{
return 0;
}
}
/*------------------------------------------------------------------------------
Function: CheckIntraChromaPrediction
Functional description:
Check that the intra chroma prediction mode is valid!
------------------------------------------------------------------------------*/
u32 CheckIntraChromaPrediction(u32 predMode, u32 availableA, u32 availableB,
u32 availableD)
{
switch (predMode)
{
case 0: /* Intra_Chroma_DC */
break;
case 1: /* Intra_Chroma_Horizontal */
if(!availableA)
return (HANTRO_NOK);
break;
case 2: /* Intra_Chroma_Vertical */
if(!availableB)
return (HANTRO_NOK);
break;
case 3: /* Intra_Chroma_Plane */
if(!availableA || !availableB || !availableD)
return (HANTRO_NOK);
break;
default:
ASSERT(predMode < 4);
return HANTRO_NOK;
}
return (HANTRO_OK);
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,135 @@
/*------------------------------------------------------------------------------
-- --
-- This software is confidential and proprietary and may be used --
-- only as expressly authorized by a licensing agreement from --
-- --
-- Hantro Products Oy. --
-- --
-- (C) COPYRIGHT 2006 HANTRO PRODUCTS OY --
-- ALL RIGHTS RESERVED --
-- --
-- The entire notice above must be reproduced --
-- on all copies and should not be removed. --
-- --
--------------------------------------------------------------------------------
--
-- Abstract : Decode NAL unit header
--
--------------------------------------------------------------------------------
--
-- Version control information, please leave untouched.
--
-- $RCSfile: h264hwd_nal_unit.c,v $
-- $Date: 2008/05/28 11:08:48 $
-- $Revision: 1.2 $
--
------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------
Table of contents
1. Include headers
2. External compiler flags
3. Module defines
4. Local function prototypes
5. Functions
h264bsdDecodeNalUnit
------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------
1. Include headers
------------------------------------------------------------------------------*/
#include "h264hwd_nal_unit.h"
#include "h264hwd_util.h"
/*------------------------------------------------------------------------------
2. External compiler flags
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
3. Module defines
------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------
4. Local function prototypes
------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------
Function name: h264bsdDecodeNalUnit
Functional description:
Decode NAL unit header information
Inputs:
pStrmData pointer to stream data structure
Outputs:
pNalUnit NAL unit header information is stored here
Returns:
HANTRO_OK success
HANTRO_NOK invalid NAL unit header information
------------------------------------------------------------------------------*/
u32 h264bsdDecodeNalUnit(strmData_t *pStrmData, nalUnit_t *pNalUnit)
{
/* Variables */
u32 tmp;
/* Code */
ASSERT(pStrmData);
ASSERT(pNalUnit);
ASSERT(pStrmData->bitPosInWord == 0);
/* forbidden_zero_bit (not checked to be zero, errors ignored) */
tmp = h264bsdGetBits(pStrmData, 1);
/* Assuming that NAL unit starts from byte boundary <20>> don't have to check
* following 7 bits for END_OF_STREAM */
if (tmp == END_OF_STREAM)
return(HANTRO_NOK);
tmp = h264bsdGetBits(pStrmData, 2);
pNalUnit->nalRefIdc = tmp;
tmp = h264bsdGetBits(pStrmData, 5);
pNalUnit->nalUnitType = (nalUnitType_e)tmp;
DEBUG_PRINT(("NAL TYPE %d\n", tmp));
/* data partitioning NAL units not supported */
if ( (tmp == NAL_CODED_SLICE_DP_A) ||
(tmp == NAL_CODED_SLICE_DP_B) ||
(tmp == NAL_CODED_SLICE_DP_C) )
{
ERROR_PRINT(("DP slices not allowed!!!"));
return(HANTRO_NOK);
}
/* nal_ref_idc shall not be zero for these nal_unit_types */
if ( ( (tmp == NAL_SEQ_PARAM_SET) || (tmp == NAL_PIC_PARAM_SET) ||
(tmp == NAL_CODED_SLICE_IDR) ) && (pNalUnit->nalRefIdc == 0) )
{
ERROR_PRINT(("nal_ref_idc shall not be zero!!!"));
return(HANTRO_NOK);
}
/* nal_ref_idc shall be zero for these nal_unit_types */
else if ( ( (tmp == NAL_SEI) || (tmp == NAL_ACCESS_UNIT_DELIMITER) ||
(tmp == NAL_END_OF_SEQUENCE) || (tmp == NAL_END_OF_STREAM) ||
(tmp == NAL_FILLER_DATA) ) && (pNalUnit->nalRefIdc != 0) )
{
ERROR_PRINT(("nal_ref_idc shall be zero!!!"));
return(HANTRO_NOK);
}
return(HANTRO_OK);
}

View File

@ -0,0 +1,395 @@
/*------------------------------------------------------------------------------
-- --
-- This software is confidential and proprietary and may be used --
-- only as expressly authorized by a licensing agreement from --
-- --
-- Hantro Products Oy. --
-- --
-- (C) COPYRIGHT 2006 HANTRO PRODUCTS OY --
-- ALL RIGHTS RESERVED --
-- --
-- The entire notice above must be reproduced --
-- on all copies and should not be removed. --
-- --
--------------------------------------------------------------------------------
--
-- Abstract : Get neighbour blocks
--
--------------------------------------------------------------------------------
--
-- Version control information, please leave untouched.
--
-- $RCSfile: h264hwd_neighbour.c,v $
-- $Date: 2008/03/13 12:48:06 $
-- $Revision: 1.1 $
--
------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------
Table of contents
1. Include headers
2. External compiler flags
3. Module defines
4. Local function prototypes
5. Functions
h264bsdInitMbNeighbours
h264bsdGetNeighbourMb
h264bsdNeighbour4x4BlockA
h264bsdNeighbour4x4BlockB
h264bsdNeighbour4x4BlockC
h264bsdNeighbour4x4BlockD
------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------
1. Include headers
------------------------------------------------------------------------------*/
#include "h264hwd_neighbour.h"
#include "h264hwd_util.h"
/*------------------------------------------------------------------------------
2. External compiler flags
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
3. Module defines
------------------------------------------------------------------------------*/
/* Following four tables indicate neighbours of each block of a macroblock.
* First 16 values are for luma blocks, next 4 values for Cb and last 4
* values for Cr. Elements of the table indicate to which macroblock the
* neighbour block belongs and the index of the neighbour block in question.
* Indexing of the blocks goes as follows
*
* Y Cb Cr
* 0 1 4 5 16 17 20 21
* 2 3 6 7 18 19 22 23
* 8 9 12 13
* 10 11 14 15
*/
/* left neighbour for each block */
static const neighbour_t N_A_4x4B[24] = {
{MB_A,5}, {MB_CURR,0}, {MB_A,7}, {MB_CURR,2},
{MB_CURR,1}, {MB_CURR,4}, {MB_CURR,3}, {MB_CURR,6},
{MB_A,13}, {MB_CURR,8}, {MB_A,15}, {MB_CURR,10},
{MB_CURR,9}, {MB_CURR,12},{MB_CURR,11},{MB_CURR,14},
{MB_A,17}, {MB_CURR,16},{MB_A,19}, {MB_CURR,18},
{MB_A,21}, {MB_CURR,20},{MB_A,23}, {MB_CURR,22} };
/* above neighbour for each block */
static const neighbour_t N_B_4x4B[24] = {
{MB_B,10}, {MB_B,11}, {MB_CURR,0}, {MB_CURR,1},
{MB_B,14}, {MB_B,15}, {MB_CURR,4}, {MB_CURR,5},
{MB_CURR,2}, {MB_CURR,3}, {MB_CURR,8}, {MB_CURR,9},
{MB_CURR,6}, {MB_CURR,7}, {MB_CURR,12},{MB_CURR,13},
{MB_B,18}, {MB_B,19}, {MB_CURR,16},{MB_CURR,17},
{MB_B,22}, {MB_B,23}, {MB_CURR,20},{MB_CURR,21} };
#if 0 /* not in use currently */
/* above-right neighbour for each block */
static const neighbour_t N_C_4x4B[24] = {
{MB_B,11}, {MB_B,14}, {MB_CURR,1}, {MB_NA,4},
{MB_B,15}, {MB_C,10}, {MB_CURR,5}, {MB_NA,0},
{MB_CURR,3}, {MB_CURR,6}, {MB_CURR,9}, {MB_NA,12},
{MB_CURR,7}, {MB_NA,2}, {MB_CURR,13},{MB_NA,8},
{MB_B,19}, {MB_C,18}, {MB_CURR,17},{MB_NA,16},
{MB_B,23}, {MB_C,22}, {MB_CURR,21},{MB_NA,20} };
#endif
/* above-left neighbour for each block */
static const neighbour_t N_D_4x4B[24] = {
{MB_D,15}, {MB_B,10}, {MB_A,5}, {MB_CURR,0},
{MB_B,11}, {MB_B,14}, {MB_CURR,1}, {MB_CURR,4},
{MB_A,7}, {MB_CURR,2}, {MB_A,13}, {MB_CURR,8},
{MB_CURR,3}, {MB_CURR,6}, {MB_CURR,9}, {MB_CURR,12},
{MB_D,19}, {MB_B,18}, {MB_A,17}, {MB_CURR,16},
{MB_D,23}, {MB_B,22}, {MB_A,21}, {MB_CURR,20} };
/*------------------------------------------------------------------------------
4. Local function prototypes
------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------
Function: h264bsdInitMbNeighbours
Functional description:
Initialize macroblock neighbours. Function sets neighbour
macroblock pointers in macroblock structures to point to
macroblocks on the left, above, above-right and above-left.
Pointers are set NULL if the neighbour does not fit into the
picture.
Inputs:
picWidth width of the picture in macroblocks
picSizeInMbs no need to clarify
Outputs:
pMbStorage neighbour pointers of each mbStorage structure
stored here
Returns:
none
------------------------------------------------------------------------------*/
void h264bsdInitMbNeighbours(mbStorage_t *pMbStorage, u32 picWidth,
u32 picSizeInMbs)
{
/* Variables */
u32 i, row, col;
/* Code */
ASSERT(pMbStorage);
ASSERT(picWidth);
ASSERT(picWidth <= picSizeInMbs);
ASSERT(((picSizeInMbs / picWidth) * picWidth) == picSizeInMbs);
row = col = 0;
for (i = 0; i < picSizeInMbs; i++)
{
if (col)
pMbStorage[i].mbA = pMbStorage + i - 1;
else
pMbStorage[i].mbA = NULL;
if (row)
pMbStorage[i].mbB = pMbStorage + i - picWidth;
else
pMbStorage[i].mbB = NULL;
if (row && (col < picWidth - 1))
pMbStorage[i].mbC = pMbStorage + i - (picWidth - 1);
else
pMbStorage[i].mbC = NULL;
if (row && col)
pMbStorage[i].mbD = pMbStorage + i - (picWidth + 1);
else
pMbStorage[i].mbD = NULL;
col++;
if (col == picWidth)
{
col = 0;
row++;
}
}
}
/*------------------------------------------------------------------------------
Function: h264bsdGetNeighbourMb
Functional description:
Get pointer to neighbour macroblock.
Inputs:
pMb pointer to macroblock structure of the macroblock
whose neighbour is wanted
neighbour indicates which neighbour is wanted
Outputs:
none
Returns:
pointer to neighbour macroblock
NULL if not available
------------------------------------------------------------------------------*/
mbStorage_t* h264bsdGetNeighbourMb(mbStorage_t *pMb, neighbourMb_e neighbour)
{
/* Variables */
/* Code */
ASSERT((neighbour <= MB_CURR) || (neighbour == MB_NA));
if (neighbour == MB_A)
return(pMb->mbA);
else if (neighbour == MB_B)
return(pMb->mbB);
else if (neighbour == MB_D)
return(pMb->mbD);
else if (neighbour == MB_CURR)
return(pMb);
else if (neighbour == MB_C)
return(pMb->mbC);
else
return(NULL);
}
/*------------------------------------------------------------------------------
Function: h264bsdNeighbour4x4BlockA
Functional description:
Get left neighbour of the block. Function returns pointer to
the table defined in the beginning of the file.
Inputs:
blockIndex indicates the block whose neighbours are wanted
Outputs:
Returns:
pointer to neighbour structure
------------------------------------------------------------------------------*/
const neighbour_t* h264bsdNeighbour4x4BlockA(u32 blockIndex)
{
/* Variables */
/* Code */
ASSERT(blockIndex < 24);
return(N_A_4x4B+blockIndex);
}
/*------------------------------------------------------------------------------
Function: h264bsdNeighbour4x4BlockB
Functional description:
Get above neighbour of the block. Function returns pointer to
the table defined in the beginning of the file.
Inputs:
blockIndex indicates the block whose neighbours are wanted
Outputs:
Returns:
pointer to neighbour structure
------------------------------------------------------------------------------*/
const neighbour_t* h264bsdNeighbour4x4BlockB(u32 blockIndex)
{
/* Variables */
/* Code */
ASSERT(blockIndex < 24);
return(N_B_4x4B+blockIndex);
}
/*------------------------------------------------------------------------------
Function: h264bsdNeighbour4x4BlockC
Functional description:
Get above-right neighbour of the block. Function returns pointer
to the table defined in the beginning of the file.
Inputs:
blockIndex indicates the block whose neighbours are wanted
Outputs:
Returns:
pointer to neighbour structure
------------------------------------------------------------------------------*/
#if 0 /* not used */
const neighbour_t* h264bsdNeighbour4x4BlockC(u32 blockIndex)
{
/* Variables */
/* Code */
ASSERT(blockIndex < 24);
return(N_C_4x4B+blockIndex);
}
#endif
/*------------------------------------------------------------------------------
Function: h264bsdNeighbour4x4BlockD
Functional description:
Get above-left neighbour of the block. Function returns pointer to
the table defined in the beginning of the file.
Inputs:
blockIndex indicates the block whose neighbours are wanted
Outputs:
Returns:
pointer to neighbour structure
------------------------------------------------------------------------------*/
const neighbour_t* h264bsdNeighbour4x4BlockD(u32 blockIndex)
{
/* Variables */
/* Code */
ASSERT(blockIndex < 24);
return(N_D_4x4B+blockIndex);
}
/*------------------------------------------------------------------------------
Function: h264bsdIsNeighbourAvailable
Functional description:
Check if neighbour macroblock is available. Neighbour macroblock
is considered available if it is within the picture and belongs
to the same slice as the current macroblock.
Inputs:
pMb pointer to the current macroblock
pNeighbour pointer to the neighbour macroblock
Outputs:
none
Returns:
HANTRO_TRUE neighbour is available
HANTRO_FALSE neighbour is not available
------------------------------------------------------------------------------*/
u32 h264bsdIsNeighbourAvailable(mbStorage_t *pMb, mbStorage_t *pNeighbour)
{
/* Variables */
/* Code */
if ( (pNeighbour == NULL) || (pMb->sliceId != pNeighbour->sliceId) )
return(HANTRO_FALSE);
else
return(HANTRO_TRUE);
}

View File

@ -0,0 +1,383 @@
/*------------------------------------------------------------------------------
-- --
-- This software is confidential and proprietary and may be used --
-- only as expressly authorized by a licensing agreement from --
-- --
-- Hantro Products Oy. --
-- --
-- (C) COPYRIGHT 2006 HANTRO PRODUCTS OY --
-- ALL RIGHTS RESERVED --
-- --
-- The entire notice above must be reproduced --
-- on all copies and should not be removed. --
-- --
--------------------------------------------------------------------------------
--
-- Abstract : Compute Picture Order Count (POC) for a picture
--
--------------------------------------------------------------------------------
--
-- Version control information, please leave untouched.
--
-- $RCSfile: h264hwd_pic_order_cnt.c,v $
-- $Date: 2008/07/31 09:38:41 $
-- $Revision: 1.2 $
--
------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------
Table of contents
1. Include headers
2. External compiler flags
3. Module defines
4. Local function prototypes
5. Functions
h264bsdDecodePicOrderCnt
------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------
1. Include headers
------------------------------------------------------------------------------*/
#include "h264hwd_util.h"
#include "h264hwd_pic_order_cnt.h"
/*------------------------------------------------------------------------------
2. External compiler flags
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
3. Module defines
------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------
4. Local function prototypes
------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------
Function: h264bsdDecodePicOrderCnt
Functional description:
Compute picture order count for a picture. Function implements
computation of all POC types (0, 1 and 2), type is obtained from
sps. See standard for description of the POC types and how POC is
computed for each type.
Function returns the minimum of top field and bottom field pic
order counts.
Inputs:
poc pointer to previous results
sps pointer to sequence parameter set
slicHeader pointer to current slice header, frame number and
other params needed for POC computation
pNalUnit pointer to current NAL unit structrue, function needs
to know if this is an IDR picture and also if this is
a reference picture
Outputs:
poc results stored here for computation of next POC
Returns:
picture order count
------------------------------------------------------------------------------*/
void h264bsdDecodePicOrderCnt(pocStorage_t *poc, const seqParamSet_t *sps,
const sliceHeader_t *pSliceHeader, const nalUnit_t *pNalUnit)
{
/* Variables */
u32 i;
i32 picOrderCnt;
u32 frameNumOffset, absFrameNum, picOrderCntCycleCnt;
u32 frameNumInPicOrderCntCycle;
i32 expectedDeltaPicOrderCntCycle;
/* Code */
ASSERT(poc);
ASSERT(sps);
ASSERT(pSliceHeader);
ASSERT(pNalUnit);
ASSERT(sps->picOrderCntType <= 2);
#if 0
/* JanSa: I don't think this is necessary, don't see any reason to
* increment prevFrameNum one by one instead of one big increment.
* However, standard specifies that this should be done -> if someone
* figures out any case when the outcome would be different for step by
* step increment, this part of the code should be enabled */
/* if there was a gap in frame numbering and picOrderCntType is 1 or 2 ->
* "compute" pic order counts for non-existing frames. These are not
* actually computed, but process needs to be done to update the
* prevFrameNum and prevFrameNumOffset */
if ( sps->picOrderCntType > 0 &&
pSliceHeader->frameNum != poc->prevFrameNum &&
pSliceHeader->frameNum != ((poc->prevFrameNum + 1) % sps->maxFrameNum))
{
/* use variable i for unUsedShortTermFrameNum */
i = (poc->prevFrameNum + 1) % sps->maxFrameNum;
do
{
if (poc->prevFrameNum > i)
frameNumOffset = poc->prevFrameNumOffset + sps->maxFrameNum;
else
frameNumOffset = poc->prevFrameNumOffset;
poc->prevFrameNumOffset = frameNumOffset;
poc->prevFrameNum = i;
i = (i + 1) % sps->maxFrameNum;
} while (i != pSliceHeader->frameNum);
}
#endif
/* check if current slice includes mmco equal to 5 */
poc->containsMmco5 = HANTRO_FALSE;
if (pSliceHeader->decRefPicMarking.adaptiveRefPicMarkingModeFlag)
{
i = 0;
while (pSliceHeader->decRefPicMarking.operation[i].
memoryManagementControlOperation)
{
if (pSliceHeader->decRefPicMarking.operation[i].
memoryManagementControlOperation == 5)
{
poc->containsMmco5 = HANTRO_TRUE;
break;
}
i++;
}
}
switch (sps->picOrderCntType)
{
case 0:
/* set prevPicOrderCnt values for IDR frame */
if (IS_IDR_NAL_UNIT(pNalUnit))
{
poc->prevPicOrderCntMsb = 0;
poc->prevPicOrderCntLsb = 0;
}
/* compute picOrderCntMsb (stored in picOrderCnt variable) */
if ( (pSliceHeader->picOrderCntLsb < poc->prevPicOrderCntLsb) &&
((poc->prevPicOrderCntLsb - pSliceHeader->picOrderCntLsb) >=
sps->maxPicOrderCntLsb/2) )
{
picOrderCnt = poc->prevPicOrderCntMsb +
(i32)sps->maxPicOrderCntLsb;
}
else if ((pSliceHeader->picOrderCntLsb > poc->prevPicOrderCntLsb) &&
((pSliceHeader->picOrderCntLsb - poc->prevPicOrderCntLsb) >
sps->maxPicOrderCntLsb/2) )
{
picOrderCnt = poc->prevPicOrderCntMsb -
(i32)sps->maxPicOrderCntLsb;
}
else
picOrderCnt = poc->prevPicOrderCntMsb;
/* standard specifies that prevPicOrderCntMsb is from previous
* rererence frame -> replace old value only if current frame is
* rererence frame */
if (pNalUnit->nalRefIdc)
poc->prevPicOrderCntMsb = picOrderCnt;
/* compute top field order cnt (stored in picOrderCnt) */
picOrderCnt += (i32)pSliceHeader->picOrderCntLsb;
/* standard specifies that prevPicOrderCntLsb is from previous
* rererence frame -> replace old value only if current frame is
* rererence frame */
if (pNalUnit->nalRefIdc)
{
/* if current frame contains mmco5 -> modify values to be
* stored */
if (poc->containsMmco5)
{
poc->prevPicOrderCntMsb = 0;
/* prevPicOrderCntLsb should be the top field picOrderCnt
* if previous frame included mmco5. Top field picOrderCnt
* for frames containing mmco5 is obtained by subtracting
* the picOrderCnt from original top field order count ->
* value is zero if top field was the minimum, i.e. delta
* for bottom was positive, otherwise value is
* -deltaPicOrderCntBottom */
if (pSliceHeader->deltaPicOrderCntBottom < 0 &&
!pSliceHeader->bottomFieldFlag)
poc->prevPicOrderCntLsb =
(u32)(-pSliceHeader->deltaPicOrderCntBottom);
else
poc->prevPicOrderCntLsb = 0;
/*picOrderCnt = poc->prevPicOrderCntLsb;*/
}
else
{
poc->prevPicOrderCntLsb = pSliceHeader->picOrderCntLsb;
}
}
/*if (!pSliceHeader->fieldPicFlag || !pSliceHeader->bottomFieldFlag)*/
poc->picOrderCnt[0] = picOrderCnt;
if (!pSliceHeader->fieldPicFlag)
poc->picOrderCnt[1] = picOrderCnt +
pSliceHeader->deltaPicOrderCntBottom;
else
/*else if (pSliceHeader->bottomFieldFlag)*/
poc->picOrderCnt[1] = picOrderCnt;
break;
case 1:
/* step 1 (in the description in the standard) */
if (IS_IDR_NAL_UNIT(pNalUnit))
frameNumOffset = 0;
else if (poc->prevFrameNum > pSliceHeader->frameNum)
frameNumOffset = poc->prevFrameNumOffset + sps->maxFrameNum;
else
frameNumOffset = poc->prevFrameNumOffset;
/* step 2 */
if (sps->numRefFramesInPicOrderCntCycle)
absFrameNum = frameNumOffset + pSliceHeader->frameNum;
else
absFrameNum = 0;
if (pNalUnit->nalRefIdc == 0 && absFrameNum > 0)
absFrameNum -= 1;
/* step 4 */
expectedDeltaPicOrderCntCycle = 0;
for (i = 0; i < sps->numRefFramesInPicOrderCntCycle; i++)
expectedDeltaPicOrderCntCycle += sps->offsetForRefFrame[i];
/* step 3 */
if (absFrameNum > 0)
{
picOrderCntCycleCnt =
(absFrameNum - 1)/sps->numRefFramesInPicOrderCntCycle;
frameNumInPicOrderCntCycle =
(absFrameNum - 1)%sps->numRefFramesInPicOrderCntCycle;
/* step 5 (picOrderCnt used to store expectedPicOrderCnt) */
picOrderCnt =
(i32)picOrderCntCycleCnt * expectedDeltaPicOrderCntCycle;
for (i = 0; i <= frameNumInPicOrderCntCycle; i++)
picOrderCnt += sps->offsetForRefFrame[i];
}
else
picOrderCnt = 0;
if (pNalUnit->nalRefIdc == 0)
picOrderCnt += sps->offsetForNonRefPic;
/* if current picture contains mmco5 -> set prevFrameNumOffset and
* prevFrameNum to 0 for computation of picOrderCnt of next
* frame, otherwise store frameNum and frameNumOffset to poc
* structure */
if (!poc->containsMmco5)
{
poc->prevFrameNumOffset = frameNumOffset;
poc->prevFrameNum = pSliceHeader->frameNum;
}
else
{
poc->prevFrameNumOffset = 0;
poc->prevFrameNum = 0;
picOrderCnt = 0;
}
/* step 6 */
if (!pSliceHeader->fieldPicFlag)
{
poc->picOrderCnt[0] = picOrderCnt +
pSliceHeader->deltaPicOrderCnt[0];
poc->picOrderCnt[1] = poc->picOrderCnt[0] +
sps->offsetForTopToBottomField +
pSliceHeader->deltaPicOrderCnt[1];
}
else if (!pSliceHeader->bottomFieldFlag)
poc->picOrderCnt[0] = poc->picOrderCnt[1] =
picOrderCnt + pSliceHeader->deltaPicOrderCnt[0];
else
poc->picOrderCnt[0] = poc->picOrderCnt[1] =
picOrderCnt + sps->offsetForTopToBottomField +
pSliceHeader->deltaPicOrderCnt[0];
break;
default: /* case 2 */
/* derive frameNumOffset */
if (IS_IDR_NAL_UNIT(pNalUnit))
frameNumOffset = 0;
else if (poc->prevFrameNum > pSliceHeader->frameNum)
frameNumOffset = poc->prevFrameNumOffset + sps->maxFrameNum;
else
frameNumOffset = poc->prevFrameNumOffset;
/* derive picOrderCnt (type 2 has same value for top and bottom
* field order cnts) */
if (IS_IDR_NAL_UNIT(pNalUnit))
{
picOrderCnt = 0;
}
else if (pNalUnit->nalRefIdc == 0)
{
picOrderCnt =
2 * (i32)(frameNumOffset + pSliceHeader->frameNum) - 1;
}
else
{
picOrderCnt =
2 * (i32)(frameNumOffset + pSliceHeader->frameNum);
}
poc->picOrderCnt[0] = poc->picOrderCnt[1] = picOrderCnt;
/*
if (!pSliceHeader->fieldPicFlag)
{
poc->picOrderCnt[0] = poc->picOrderCnt[1] = picOrderCnt;
}
else if (!pSliceHeader->bottomFieldFlag)
poc->picOrderCnt[0] = picOrderCnt;
else
poc->picOrderCnt[1] = picOrderCnt;
*/
/* if current picture contains mmco5 -> set prevFrameNumOffset and
* prevFrameNum to 0 for computation of picOrderCnt of next
* frame, otherwise store frameNum and frameNumOffset to poc
* structure */
if (!poc->containsMmco5)
{
poc->prevFrameNumOffset = frameNumOffset;
poc->prevFrameNum = pSliceHeader->frameNum;
}
else
{
poc->prevFrameNumOffset = 0;
poc->prevFrameNum = 0;
picOrderCnt = 0;
}
break;
}
}

View File

@ -0,0 +1,397 @@
/*------------------------------------------------------------------------------
-- --
-- This software is confidential and proprietary and may be used --
-- only as expressly authorized by a licensing agreement from --
-- --
-- Hantro Products Oy. --
-- --
-- (C) COPYRIGHT 2006 HANTRO PRODUCTS OY --
-- ALL RIGHTS RESERVED --
-- --
-- The entire notice above must be reproduced --
-- on all copies and should not be removed. --
-- --
--------------------------------------------------------------------------------
--
-- Abstract : Decode picture parameter set information from the stream
--
--------------------------------------------------------------------------------
--
-- Version control information, please leave untouched.
--
-- $RCSfile: h264hwd_pic_param_set.c,v $
-- $Date: 2008/05/28 11:10:37 $
-- $Revision: 1.5 $
--
------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------
Table of contents
1. Include headers
2. External compiler flags
3. Module defines
4. Local function prototypes
5. Functions
h264bsdDecodePicParamSet
------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------
1. Include headers
------------------------------------------------------------------------------*/
#include "h264hwd_pic_param_set.h"
#include "h264hwd_util.h"
#include "h264hwd_vlc.h"
#include "h264hwd_cfg.h"
#include "dwl.h"
#ifdef ASIC_TRACE_SUPPORT
#include "trace.h"
#endif
/*------------------------------------------------------------------------------
2. External compiler flags
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
3. Module defines
------------------------------------------------------------------------------*/
/* lookup table for ceil(log2(numSliceGroups)), i.e. number of bits needed to
* represent range [0, numSliceGroups)
*
* NOTE: if MAX_NUM_SLICE_GROUPS is higher than 8 this table has to be resized
* accordingly */
static const u32 CeilLog2NumSliceGroups[8] = {1, 1, 2, 2, 3, 3, 3, 3};
/*------------------------------------------------------------------------------
4. Local function prototypes
------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------
Function name: h264bsdDecodePicParamSet
Functional description:
Decode picture parameter set information from the stream.
Function allocates memory for
- run lengths if slice group map type is 0
- top-left and bottom-right arrays if map type is 2
- for slice group ids if map type is 6
Validity of some of the slice group mapping information depends
on the image dimensions which are not known here. Therefore the
validity has to be checked afterwards, currently in the parameter
set activation phase.
Inputs:
pStrmData pointer to stream data structure
Outputs:
pPicParamSet decoded information is stored here
Returns:
HANTRO_OK success
HANTRO_NOK failure, invalid information or end of stream
MEMORY_ALLOCATION_ERROR for memory allocation failure
------------------------------------------------------------------------------*/
void ScalingList(u8 scalingList[][64], strmData_t *pStrmData, u32 idx);
void FallbackScaling(u8 scalingList[][64], u32 idx);
u32 h264bsdDecodePicParamSet(strmData_t *pStrmData, picParamSet_t *pPicParamSet)
{
/* Variables */
u32 tmp, i, value;
i32 itmp;
/* Code */
ASSERT(pStrmData);
ASSERT(pPicParamSet);
(void) DWLmemset(pPicParamSet, 0, sizeof(picParamSet_t));
tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
&pPicParamSet->picParameterSetId);
if (tmp != HANTRO_OK)
return(tmp);
if (pPicParamSet->picParameterSetId >= MAX_NUM_PIC_PARAM_SETS)
{
ERROR_PRINT("pic_parameter_set_id");
return(HANTRO_NOK);
}
tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
&pPicParamSet->seqParameterSetId);
if (tmp != HANTRO_OK)
return(tmp);
if (pPicParamSet->seqParameterSetId >= MAX_NUM_SEQ_PARAM_SETS)
{
ERROR_PRINT("seq_param_set_id");
return(HANTRO_NOK);
}
/* entropy_coding_mode_flag, shall be 0 for baseline profile */
tmp = h264bsdGetBits(pStrmData, 1);
if (tmp == END_OF_STREAM)
return(HANTRO_NOK);
pPicParamSet->entropyCodingModeFlag = tmp;
tmp = h264bsdGetBits(pStrmData, 1);
if (tmp == END_OF_STREAM)
return(HANTRO_NOK);
pPicParamSet->picOrderPresentFlag = (tmp == 1) ? HANTRO_TRUE : HANTRO_FALSE;
/* num_slice_groups_minus1 */
tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
if (tmp != HANTRO_OK)
return(tmp);
pPicParamSet->numSliceGroups = value + 1;
if (pPicParamSet->numSliceGroups > MAX_NUM_SLICE_GROUPS)
{
ERROR_PRINT("num_slice_groups_minus1");
return(HANTRO_NOK);
}
/* decode slice group mapping information if more than one slice groups */
if (pPicParamSet->numSliceGroups > 1)
{
#ifdef ASIC_TRACE_SUPPORT
trace_h264DecodingTools.sliceGroups = 1;
#endif
tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
&pPicParamSet->sliceGroupMapType);
if (tmp != HANTRO_OK)
return(tmp);
if (pPicParamSet->sliceGroupMapType > 6)
{
ERROR_PRINT("slice_group_map_type");
return(HANTRO_NOK);
}
if (pPicParamSet->sliceGroupMapType == 0)
{
ALLOCATE(pPicParamSet->runLength,
pPicParamSet->numSliceGroups, u32);
if (pPicParamSet->runLength == NULL)
return(MEMORY_ALLOCATION_ERROR);
for (i = 0; i < pPicParamSet->numSliceGroups; i++)
{
tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
if (tmp != HANTRO_OK)
return(tmp);
pPicParamSet->runLength[i] = value+1;
/* param values checked in CheckPps() */
}
}
else if (pPicParamSet->sliceGroupMapType == 2)
{
ALLOCATE(pPicParamSet->topLeft,
pPicParamSet->numSliceGroups - 1, u32);
ALLOCATE(pPicParamSet->bottomRight,
pPicParamSet->numSliceGroups - 1, u32);
if (pPicParamSet->topLeft == NULL ||
pPicParamSet->bottomRight == NULL)
return(MEMORY_ALLOCATION_ERROR);
for (i = 0; i < pPicParamSet->numSliceGroups - 1; i++)
{
tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
if (tmp != HANTRO_OK)
return(tmp);
pPicParamSet->topLeft[i] = value;
tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
if (tmp != HANTRO_OK)
return(tmp);
pPicParamSet->bottomRight[i] = value;
/* param values checked in CheckPps() */
}
}
else if ( (pPicParamSet->sliceGroupMapType == 3) ||
(pPicParamSet->sliceGroupMapType == 4) ||
(pPicParamSet->sliceGroupMapType == 5) )
{
tmp = h264bsdGetBits(pStrmData, 1);
if (tmp == END_OF_STREAM)
return(HANTRO_NOK);
pPicParamSet->sliceGroupChangeDirectionFlag =
(tmp == 1) ? HANTRO_TRUE : HANTRO_FALSE;
tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
if (tmp != HANTRO_OK)
return(tmp);
pPicParamSet->sliceGroupChangeRate = value + 1;
/* param value checked in CheckPps() */
}
else if (pPicParamSet->sliceGroupMapType == 6)
{
tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
if (tmp != HANTRO_OK)
return(tmp);
pPicParamSet->picSizeInMapUnits = value + 1;
ALLOCATE(pPicParamSet->sliceGroupId,
pPicParamSet->picSizeInMapUnits, u32);
if (pPicParamSet->sliceGroupId == NULL)
return(MEMORY_ALLOCATION_ERROR);
/* determine number of bits needed to represent range
* [0, numSliceGroups) */
tmp = CeilLog2NumSliceGroups[pPicParamSet->numSliceGroups-1];
for (i = 0; i < pPicParamSet->picSizeInMapUnits; i++)
{
pPicParamSet->sliceGroupId[i] = h264bsdGetBits(pStrmData, tmp);
if ( pPicParamSet->sliceGroupId[i] >=
pPicParamSet->numSliceGroups )
{
ERROR_PRINT("slice_group_id");
return(HANTRO_NOK);
}
}
}
}
/* num_ref_idx_l0_active_minus1 */
tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
if (tmp != HANTRO_OK)
return(tmp);
if (value > 31)
{
ERROR_PRINT("num_ref_idx_l0_active_minus1");
return(HANTRO_NOK);
}
pPicParamSet->numRefIdxL0Active = value + 1;
/* num_ref_idx_l1_active_minus1 */
tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
if (tmp != HANTRO_OK)
return(tmp);
if (value > 31)
{
ERROR_PRINT("num_ref_idx_l1_active_minus1");
return(HANTRO_NOK);
}
pPicParamSet->numRefIdxL1Active = value + 1;
/* weighted_pred_flag, this shall be 0 for baseline profile */
tmp = h264bsdGetBits(pStrmData, 1);
if (tmp == END_OF_STREAM)
return(HANTRO_NOK);
pPicParamSet->weightedPredFlag = tmp;
/* weighted_bipred_idc */
tmp = h264bsdGetBits(pStrmData, 2);
if (tmp > 2)
{
ERROR_PRINT("weighted_bipred_idc");
return(HANTRO_NOK);
}
pPicParamSet->weightedBiPredIdc = tmp;
/* pic_init_qp_minus26 */
tmp = h264bsdDecodeExpGolombSigned(pStrmData, &itmp);
if (tmp != HANTRO_OK)
return(tmp);
if ((itmp < -26) || (itmp > 25))
{
ERROR_PRINT("pic_init_qp_minus26");
return(HANTRO_NOK);
}
pPicParamSet->picInitQp = (u32)(itmp + 26);
/* pic_init_qs_minus26 */
tmp = h264bsdDecodeExpGolombSigned(pStrmData, &itmp);
if (tmp != HANTRO_OK)
return(tmp);
if ((itmp < -26) || (itmp > 25))
{
ERROR_PRINT("pic_init_qs_minus26");
return(HANTRO_NOK);
}
tmp = h264bsdDecodeExpGolombSigned(pStrmData, &itmp);
if (tmp != HANTRO_OK)
return(tmp);
if ((itmp < -12) || (itmp > 12))
{
ERROR_PRINT("chroma_qp_index_offset");
return(HANTRO_NOK);
}
pPicParamSet->chromaQpIndexOffset = itmp;
tmp = h264bsdGetBits(pStrmData, 1);
if (tmp == END_OF_STREAM)
return(HANTRO_NOK);
pPicParamSet->deblockingFilterControlPresentFlag =
(tmp == 1) ? HANTRO_TRUE : HANTRO_FALSE;
tmp = h264bsdGetBits(pStrmData, 1);
if (tmp == END_OF_STREAM)
return(HANTRO_NOK);
pPicParamSet->constrainedIntraPredFlag = (tmp == 1) ? HANTRO_TRUE : HANTRO_FALSE;
tmp = h264bsdGetBits(pStrmData, 1);
if (tmp == END_OF_STREAM)
return(HANTRO_NOK);
pPicParamSet->redundantPicCntPresentFlag = (tmp == 1) ? HANTRO_TRUE : HANTRO_FALSE;
if (h264bsdMoreRbspData(pStrmData))
{
tmp = h264bsdGetBits(pStrmData, 1);
if (tmp == END_OF_STREAM)
return(HANTRO_NOK);
pPicParamSet->transform8x8Flag = tmp;
/* pic_scaling_matrix_present_flag */
tmp = h264bsdGetBits(pStrmData, 1);
#ifdef ASIC_TRACE_SUPPORT
if (tmp)
trace_h264DecodingTools.scalingMatrixPresentType.pic = 1;
#endif
if (tmp == END_OF_STREAM)
return(HANTRO_NOK);
pPicParamSet->scalingMatrixPresentFlag = tmp;
if (tmp)
{
for (i = 0; i < 6+2*pPicParamSet->transform8x8Flag; i++)
{
tmp = h264bsdGetBits(pStrmData, 1);
pPicParamSet->scalingListPresent[i] = tmp;
if (tmp)
{
ScalingList(pPicParamSet->scalingList, pStrmData, i);
}
else
FallbackScaling(pPicParamSet->scalingList, i);
}
}
tmp = h264bsdDecodeExpGolombSigned(pStrmData, &itmp);
if (tmp != HANTRO_OK)
return(tmp);
if ((itmp < -12) || (itmp > 12))
{
ERROR_PRINT("second_chroma_qp_index_offset");
return(HANTRO_NOK);
}
pPicParamSet->chromaQpIndexOffset2 = itmp;
}
else
{
pPicParamSet->scalingMatrixPresentFlag = 0;
pPicParamSet->transform8x8Flag = 0;
pPicParamSet->chromaQpIndexOffset2 = pPicParamSet->chromaQpIndexOffset;
}
tmp = h264bsdRbspTrailingBits(pStrmData);
/* ignore possible errors in trailing bits of parameters sets */
return(HANTRO_OK);
}

View File

@ -0,0 +1,800 @@
/*------------------------------------------------------------------------------
-- --
-- This software is confidential and proprietary and may be used --
-- only as expressly authorized by a licensing agreement from --
-- --
-- Hantro Products Oy. --
-- --
-- (C) COPYRIGHT 2006 HANTRO PRODUCTS OY --
-- ALL RIGHTS RESERVED --
-- --
-- The entire notice above must be reproduced --
-- on all copies and should not be removed. --
-- --
--------------------------------------------------------------------------------
--
-- Abstract : Decode seq parameter set information from the stream
--
--------------------------------------------------------------------------------
--
-- Version control information, please leave untouched.
--
-- $RCSfile: h264hwd_seq_param_set.c,v $
-- $Date: 2008/11/28 11:34:21 $
-- $Revision: 1.9 $
--
------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------
1. Include headers
------------------------------------------------------------------------------*/
#include "h264hwd_seq_param_set.h"
#include "h264hwd_util.h"
#include "h264hwd_vlc.h"
#include "h264hwd_vui.h"
#include "h264hwd_cfg.h"
#include "dwl.h"
#ifdef ASIC_TRACE_SUPPORT
#include "trace.h"
#endif
/*------------------------------------------------------------------------------
2. External compiler flags
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
3. Module defines
------------------------------------------------------------------------------*/
/* enumeration to indicate invalid return value from the GetDpbSize function */
enum {INVALID_DPB_SIZE = 0x7FFFFFFF};
const u32 default4x4Intra[16] =
{6,13,13,20,20,20,28,28,28,28,32,32,32,37,37,42};
const u32 default4x4Inter[16] =
{10,14,14,20,20,20,24,24,24,24,27,27,27,30,30,34};
const u32 default8x8Intra[64] =
{ 6,10,10,13,11,13,16,16,16,16,18,18,18,18,18,23,
23,23,23,23,23,25,25,25,25,25,25,25,27,27,27,27,
27,27,27,27,29,29,29,29,29,29,29,31,31,31,31,31,
31,33,33,33,33,33,36,36,36,36,38,38,38,40,40,42};
const u32 default8x8Inter[64] =
{ 9,13,13,15,13,15,17,17,17,17,19,19,19,19,19,21,
21,21,21,21,21,22,22,22,22,22,22,22,24,24,24,24,
24,24,24,24,25,25,25,25,25,25,25,27,27,27,27,27,
27,28,28,28,28,28,30,30,30,30,32,32,32,33,33,35};
static const u32 zigZag4x4[16] = {
0, 1, 4, 8, 5, 2, 3, 6, 9, 12, 13, 10, 7, 11, 14, 15 };
static const u32 zigZag8x8[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 };
/*------------------------------------------------------------------------------
4. Local function prototypes
------------------------------------------------------------------------------*/
static u32 GetDpbSize(u32 picSizeInMbs, u32 levelIdc);
/*------------------------------------------------------------------------------
Function name: h264bsdDecodeSeqParamSet
Functional description:
Decode sequence parameter set information from the stream.
Function allocates memory for offsetForRefFrame array if
picture order count type is 1 and numRefFramesInPicOrderCntCycle
is greater than zero.
Inputs:
pStrmData pointer to stream data structure
Outputs:
pSeqParamSet decoded information is stored here
Returns:
HANTRO_OK success
HANTRO_NOK failure, invalid information or end of stream
MEMORY_ALLOCATION_ERROR for memory allocation failure
------------------------------------------------------------------------------*/
void ScalingList(u8 scalingList[][64], strmData_t *pStrmData, u32 idx)
{
u32 lastScale = 8, nextScale = 8;
u32 i, size;
u32 useDefault = 0;
i32 delta;
const u32 *defList[8] = {
default4x4Intra, default4x4Intra, default4x4Intra,
default4x4Inter, default4x4Inter, default4x4Inter,
default8x8Intra, default8x8Inter };
const u32 *zigZag;
size = idx < 6 ? 16 : 64;
zigZag = idx < 6 ? zigZag4x4 : zigZag8x8;
for (i = 0; i < size; i++)
{
if (nextScale)
{
u32 tmp = h264bsdDecodeExpGolombSigned(pStrmData, &delta);
(void)tmp; /* TODO: should we check for error here? */
nextScale = (lastScale + delta + 256)&0xFF;
if (!i && !nextScale)
{
useDefault = 1;
break;
}
}
scalingList[idx][zigZag[i]] = nextScale ? nextScale : lastScale;
lastScale = scalingList[idx][zigZag[i]];
}
if (useDefault)
for (i = 0; i < size; i++)
scalingList[idx][zigZag[i]] = defList[idx][i];
}
void FallbackScaling(u8 scalingList[][64], u32 idx)
{
u32 i;
ASSERT(idx < 8);
switch (idx)
{
case 0:
for (i = 0; i < 16; i++)
scalingList[idx][zigZag4x4[i]] = default4x4Intra[i];
break;
case 3:
for (i = 0; i < 16; i++)
scalingList[idx][zigZag4x4[i]] = default4x4Inter[i];
break;
case 6:
for (i = 0; i < 64; i++)
scalingList[idx][zigZag8x8[i]] = default8x8Intra[i];
break;
case 7:
for (i = 0; i < 64; i++)
scalingList[idx][zigZag8x8[i]] = default8x8Inter[i];
break;
default:
for (i = 0; i < 16; i++)
scalingList[idx][i] = scalingList[idx-1][i];
break;
}
}
u32 h264bsdDecodeSeqParamSet(strmData_t *pStrmData, seqParamSet_t *pSeqParamSet)
{
/* Variables */
u32 tmp, i, value;
/* Code */
ASSERT(pStrmData);
ASSERT(pSeqParamSet);
(void)DWLmemset(pSeqParamSet, 0, sizeof(seqParamSet_t));
/* profile_idc */
tmp = h264bsdGetBits(pStrmData, 8);
if (tmp == END_OF_STREAM)
return(HANTRO_NOK);
if (tmp != 66)
{
DEBUG_PRINT(("NOT BASELINE PROFILE %d\n", tmp));
}
#ifdef ASIC_TRACE_SUPPORT
if (tmp==66)
trace_h264DecodingTools.profileType.baseline = 1;
if (tmp==77)
trace_h264DecodingTools.profileType.main = 1;
if (tmp == 100)
trace_h264DecodingTools.profileType.high = 1;
#endif
pSeqParamSet->profileIdc = tmp;
/* constrained_set0_flag */
tmp = h264bsdGetBits(pStrmData, 1);
pSeqParamSet->constrained_set0_flag = tmp;
/* constrained_set1_flag */
tmp = h264bsdGetBits(pStrmData, 1);
pSeqParamSet->constrained_set1_flag = tmp;
/* constrained_set2_flag */
tmp = h264bsdGetBits(pStrmData, 1);
pSeqParamSet->constrained_set2_flag = tmp;
/* constrained_set3_flag */
tmp = h264bsdGetBits(pStrmData, 1);
pSeqParamSet->constrained_set3_flag = tmp;
if (tmp == END_OF_STREAM)
return(HANTRO_NOK);
/* reserved_zero_4bits, values of these bits shall be ignored */
tmp = h264bsdGetBits(pStrmData, 4);
if (tmp == END_OF_STREAM)
{
ERROR_PRINT("reserved_zero_4bits");
return(HANTRO_NOK);
}
tmp = h264bsdGetBits(pStrmData, 8);
if (tmp == END_OF_STREAM)
{
ERROR_PRINT("level_idc");
return(HANTRO_NOK);
}
pSeqParamSet->levelIdc = tmp;
tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
&pSeqParamSet->seqParameterSetId);
if (tmp != HANTRO_OK)
return(tmp);
if (pSeqParamSet->seqParameterSetId >= MAX_NUM_SEQ_PARAM_SETS)
{
ERROR_PRINT("seq_param_set_id");
return(HANTRO_NOK);
}
if( pSeqParamSet->profileIdc >= 100 )
{
/* chroma_format_idc */
tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
&value);
if (tmp != HANTRO_OK)
return(tmp);
if( tmp > 1 )
return(HANTRO_NOK);
pSeqParamSet->chromaFormatIdc = value;
if (pSeqParamSet->chromaFormatIdc == 0)
pSeqParamSet->monoChrome = 1;
/* residual_colour_transform_flag (skipped) */
/* bit_depth_luma_minus8 */
tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
&value);
if (tmp != HANTRO_OK)
return(tmp);
/* bit_depth_chroma_minus8 */
tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
&value);
if (tmp != HANTRO_OK)
return(tmp);
/* qpprime_y_zero_transform_bypass_flag */
tmp = h264bsdGetBits(pStrmData, 1);
if (tmp == END_OF_STREAM)
return(HANTRO_NOK);
/* seq_scaling_matrix_present_flag */
tmp = h264bsdGetBits(pStrmData, 1);
#ifdef ASIC_TRACE_SUPPORT
if (tmp)
trace_h264DecodingTools.scalingMatrixPresentType.seq = 1;
#endif
if (tmp == END_OF_STREAM)
return(HANTRO_NOK);
pSeqParamSet->scalingMatrixPresentFlag = tmp;
if (tmp)
{
for (i = 0; i < 8; i++)
{
tmp = h264bsdGetBits(pStrmData, 1);
pSeqParamSet->scalingListPresent[i] = tmp;
if (tmp)
{
ScalingList(pSeqParamSet->scalingList, pStrmData, i);
}
else
FallbackScaling(pSeqParamSet->scalingList, i);
}
}
}
else
{
pSeqParamSet->chromaFormatIdc = 1; /* 4:2:0 */
pSeqParamSet->scalingMatrixPresentFlag = 0;
}
/* log2_max_frame_num_minus4 */
tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
if (tmp != HANTRO_OK)
{
ERROR_PRINT("log2_max_frame_num_minus4");
return(tmp);
}
if (value > 12)
{
ERROR_PRINT("log2_max_frame_num_minus4");
return(HANTRO_NOK);
}
/* maxFrameNum = 2^(log2_max_frame_num_minus4 + 4) */
pSeqParamSet->maxFrameNum = 1 << (value+4);
/* valid POC types are 0, 1 and 2 */
tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
if (tmp != HANTRO_OK)
{
ERROR_PRINT("pic_order_cnt_type");
return(tmp);
}
if (value > 2)
{
ERROR_PRINT("pic_order_cnt_type");
return(HANTRO_NOK);
}
pSeqParamSet->picOrderCntType = value;
if (pSeqParamSet->picOrderCntType == 0)
{
/* log2_max_pic_order_cnt_lsb_minus4 */
tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
if (tmp != HANTRO_OK)
return(tmp);
if (value > 12)
{
ERROR_PRINT("log2_max_pic_order_cnt_lsb_minus4");
return(HANTRO_NOK);
}
/* maxPicOrderCntLsb = 2^(log2_max_pic_order_cnt_lsb_minus4 + 4) */
pSeqParamSet->maxPicOrderCntLsb = 1 << (value+4);
}
else if (pSeqParamSet->picOrderCntType == 1)
{
tmp = h264bsdGetBits(pStrmData, 1);
if (tmp == END_OF_STREAM)
return(HANTRO_NOK);
pSeqParamSet->deltaPicOrderAlwaysZeroFlag = (tmp == 1) ? HANTRO_TRUE : HANTRO_FALSE;
tmp = h264bsdDecodeExpGolombSigned(pStrmData,
&pSeqParamSet->offsetForNonRefPic);
if (tmp != HANTRO_OK)
return(tmp);
tmp = h264bsdDecodeExpGolombSigned(pStrmData,
&pSeqParamSet->offsetForTopToBottomField);
if (tmp != HANTRO_OK)
return(tmp);
tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
&pSeqParamSet->numRefFramesInPicOrderCntCycle);
if (tmp != HANTRO_OK)
return(tmp);
if (pSeqParamSet->numRefFramesInPicOrderCntCycle > 255)
{
ERROR_PRINT("num_ref_frames_in_pic_order_cnt_cycle");
return(HANTRO_NOK);
}
if (pSeqParamSet->numRefFramesInPicOrderCntCycle)
{
/* NOTE: This has to be freed somewhere! */
ALLOCATE(pSeqParamSet->offsetForRefFrame,
pSeqParamSet->numRefFramesInPicOrderCntCycle, i32);
if (pSeqParamSet->offsetForRefFrame == NULL)
return(MEMORY_ALLOCATION_ERROR);
for (i = 0; i < pSeqParamSet->numRefFramesInPicOrderCntCycle; i++)
{
tmp = h264bsdDecodeExpGolombSigned(pStrmData,
pSeqParamSet->offsetForRefFrame + i);
if (tmp != HANTRO_OK)
return(tmp);
}
}
else
{
pSeqParamSet->offsetForRefFrame = NULL;
}
}
tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
&pSeqParamSet->numRefFrames);
if (tmp != HANTRO_OK)
return(tmp);
if (pSeqParamSet->numRefFrames > MAX_NUM_REF_PICS)
{
ERROR_PRINT("num_ref_frames");
return(HANTRO_NOK);
}
tmp = h264bsdGetBits(pStrmData, 1);
if (tmp == END_OF_STREAM)
return(HANTRO_NOK);
pSeqParamSet->gapsInFrameNumValueAllowedFlag = (tmp == 1) ? HANTRO_TRUE : HANTRO_FALSE;
tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
if (tmp != HANTRO_OK)
return(tmp);
pSeqParamSet->picWidthInMbs = value + 1;
tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
if (tmp != HANTRO_OK)
return(tmp);
pSeqParamSet->picHeightInMbs = value + 1;
/* frame_mbs_only_flag, shall be 1 for baseline profile */
tmp = h264bsdGetBits(pStrmData, 1);
if (tmp == END_OF_STREAM)
return(HANTRO_NOK);
pSeqParamSet->frameMbsOnlyFlag = tmp;
if (!pSeqParamSet->frameMbsOnlyFlag)
{
pSeqParamSet->mbAdaptiveFrameFieldFlag =
h264bsdGetBits(pStrmData, 1);
pSeqParamSet->picHeightInMbs *= 2;
}
/* direct_8x8_inference_flag */
tmp = h264bsdGetBits(pStrmData, 1);
if (tmp == END_OF_STREAM)
return(HANTRO_NOK);
pSeqParamSet->direct8x8InferenceFlag = tmp;
tmp = h264bsdGetBits(pStrmData, 1);
if (tmp == END_OF_STREAM)
return(HANTRO_NOK);
pSeqParamSet->frameCroppingFlag = (tmp == 1) ? HANTRO_TRUE : HANTRO_FALSE;
#ifdef ASIC_TRACE_SUPPORT
if (tmp)
trace_h264DecodingTools.imageCropping = 1;
#endif
if (pSeqParamSet->frameCroppingFlag)
{
tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
&pSeqParamSet->frameCropLeftOffset);
if (tmp != HANTRO_OK)
return(tmp);
tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
&pSeqParamSet->frameCropRightOffset);
if (tmp != HANTRO_OK)
return(tmp);
tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
&pSeqParamSet->frameCropTopOffset);
if (tmp != HANTRO_OK)
return(tmp);
tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
&pSeqParamSet->frameCropBottomOffset);
if (tmp != HANTRO_OK)
return(tmp);
/* check that frame cropping params are valid, parameters shall
* specify non-negative area within the original picture */
if ( ( (i32)pSeqParamSet->frameCropLeftOffset >
( 8 * (i32)pSeqParamSet->picWidthInMbs -
((i32)pSeqParamSet->frameCropRightOffset + 1) ) ) ||
( (i32)pSeqParamSet->frameCropTopOffset >
( 8 * (i32)pSeqParamSet->picHeightInMbs -
((i32)pSeqParamSet->frameCropBottomOffset + 1) ) ) )
{
ERROR_PRINT("frame_cropping");
return(HANTRO_NOK);
}
}
/* check that image dimensions and levelIdc match */
tmp = pSeqParamSet->picWidthInMbs * pSeqParamSet->picHeightInMbs;
value = GetDpbSize(tmp, pSeqParamSet->levelIdc);
if (value == INVALID_DPB_SIZE || pSeqParamSet->numRefFrames > value)
{
DEBUG_PRINT(("WARNING! Invalid DPB size based on SPS Level!\n"));
DEBUG_PRINT(("WARNING! Using num_ref_frames =%d for DPB size!\n",
pSeqParamSet->numRefFrames));
/* set maxDpbSize to 1 if numRefFrames is zero */
value = pSeqParamSet->numRefFrames ? pSeqParamSet->numRefFrames : 1;
}
pSeqParamSet->maxDpbSize = value;
tmp = h264bsdGetBits(pStrmData, 1);
if (tmp == END_OF_STREAM)
return(HANTRO_NOK);
pSeqParamSet->vuiParametersPresentFlag = (tmp == 1) ? HANTRO_TRUE : HANTRO_FALSE;
/* VUI */
if (pSeqParamSet->vuiParametersPresentFlag)
{
ALLOCATE(pSeqParamSet->vuiParameters, 1, vuiParameters_t);
if (pSeqParamSet->vuiParameters == NULL)
return(MEMORY_ALLOCATION_ERROR);
tmp = h264bsdDecodeVuiParameters(pStrmData,
pSeqParamSet->vuiParameters);
if (tmp == END_OF_STREAM)
{
pSeqParamSet->vuiParameters->bitstreamRestrictionFlag |= 1;
pSeqParamSet->vuiParameters->maxDecFrameBuffering =
pSeqParamSet->maxDpbSize;
}
else if (tmp != HANTRO_OK)
return(tmp);
/* check numReorderFrames and maxDecFrameBuffering */
if (pSeqParamSet->vuiParameters->bitstreamRestrictionFlag)
{
if (pSeqParamSet->vuiParameters->numReorderFrames >
pSeqParamSet->vuiParameters->maxDecFrameBuffering ||
pSeqParamSet->vuiParameters->maxDecFrameBuffering <
pSeqParamSet->numRefFrames ||
pSeqParamSet->vuiParameters->maxDecFrameBuffering >
pSeqParamSet->maxDpbSize)
{
ERROR_PRINT("Not valid vuiParameters->bitstreamRestriction");
//Add by Sim
//<2F>ֻ<EFBFBD><D6BB><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>Щ<EFBFBD>ֻ<EFBFBD><D6BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƶ<EFBFBD><C6B5><EFBFBD>ô<EFBFBD><C3B4><EFBFBD><EFBFBD>ܴ<EFBFBD><DCB4>󷵻<EFBFBD>
//return(HANTRO_NOK);
}
/* standard says that "the sequence shall not require a DPB with
* size of more than max(1, maxDecFrameBuffering) */
pSeqParamSet->maxDpbSize =
MAX(1, pSeqParamSet->vuiParameters->maxDecFrameBuffering);
}
}
tmp = h264bsdRbspTrailingBits(pStrmData);
/* ignore possible errors in trailing bits of parameters sets */
return(HANTRO_OK);
}
/*------------------------------------------------------------------------------
Function: GetDpbSize
Functional description:
Get size of the DPB in frames. Size is determined based on the
picture size and MaxDPB for the specified level. These determine
how many pictures may fit into to the buffer. However, the size
is also limited to a maximum of 16 frames and therefore function
returns the minimum of the determined size and 16.
Inputs:
picSizeInMbs number of macroblocks in the picture
levelIdc indicates the level
Outputs:
none
Returns:
size of the DPB in frames
INVALID_DPB_SIZE when invalid levelIdc specified or picSizeInMbs
is higher than supported by the level in question
------------------------------------------------------------------------------*/
u32 GetDpbSize(u32 picSizeInMbs, u32 levelIdc)
{
/* Variables */
u32 tmp;
u32 maxPicSizeInMbs;
/* Code */
ASSERT(picSizeInMbs);
/* use tmp as the size of the DPB in bytes, computes as 1024 * MaxDPB
* (from table A-1 in Annex A) */
switch (levelIdc)
{
case 10:
tmp = 152064;
maxPicSizeInMbs = 99;
break;
case 11:
tmp = 345600;
maxPicSizeInMbs = 396;
break;
case 12:
tmp = 912384;
maxPicSizeInMbs = 396;
break;
case 13:
tmp = 912384;
maxPicSizeInMbs = 396;
break;
case 20:
tmp = 912384;
maxPicSizeInMbs = 396;
break;
case 21:
tmp = 1824768;
maxPicSizeInMbs = 792;
break;
case 22:
tmp = 3110400;
maxPicSizeInMbs = 1620;
break;
case 30:
tmp = 3110400;
maxPicSizeInMbs = 1620;
break;
case 31:
tmp = 6912000;
maxPicSizeInMbs = 3600;
break;
case 32:
tmp = 7864320;
maxPicSizeInMbs = 5120;
break;
case 40:
tmp = 12582912;
maxPicSizeInMbs = 8192;
break;
case 41:
tmp = 12582912;
maxPicSizeInMbs = 8192;
break;
case 42:
tmp = 12582912;
maxPicSizeInMbs = 8192;
break;
case 50:
/* standard says 42301440 here, but corrigendum "corrects" this to
* 42393600 */
tmp = 42393600;
maxPicSizeInMbs = 22080;
break;
case 51:
tmp = 70778880;
maxPicSizeInMbs = 36864;
break;
default:
return(INVALID_DPB_SIZE);
}
/* this is not "correct" return value! However, it results in error in
* decoding and this was easiest place to check picture size */
if (picSizeInMbs > maxPicSizeInMbs)
return(INVALID_DPB_SIZE);
tmp /= (picSizeInMbs*384);
return(MIN(tmp, 16));
}
/*------------------------------------------------------------------------------
Function name: h264bsdCompareSeqParamSets
Functional description:
Compare two sequence parameter sets.
Inputs:
pSps1 pointer to a sequence parameter set
pSps2 pointer to another sequence parameter set
Outputs:
0 sequence parameter sets are equal
1 otherwise
------------------------------------------------------------------------------*/
u32 h264bsdCompareSeqParamSets(seqParamSet_t *pSps1, seqParamSet_t *pSps2)
{
/* Variables */
u32 i;
/* Code */
ASSERT(pSps1);
ASSERT(pSps2);
/* first compare parameters whose existence does not depend on other
* parameters and only compare the rest of the params if these are equal */
if (pSps1->profileIdc == pSps2->profileIdc &&
pSps1->levelIdc == pSps2->levelIdc &&
pSps1->maxFrameNum == pSps2->maxFrameNum &&
pSps1->picOrderCntType == pSps2->picOrderCntType &&
pSps1->numRefFrames == pSps2->numRefFrames &&
pSps1->gapsInFrameNumValueAllowedFlag ==
pSps2->gapsInFrameNumValueAllowedFlag &&
pSps1->picWidthInMbs == pSps2->picWidthInMbs &&
pSps1->picHeightInMbs == pSps2->picHeightInMbs &&
pSps1->frameCroppingFlag == pSps2->frameCroppingFlag &&
pSps1->frameMbsOnlyFlag == pSps2->frameMbsOnlyFlag &&
pSps1->vuiParametersPresentFlag == pSps2->vuiParametersPresentFlag &&
pSps1->scalingMatrixPresentFlag == pSps2->scalingMatrixPresentFlag)
{
if (pSps1->picOrderCntType == 0)
{
if (pSps1->maxPicOrderCntLsb != pSps2->maxPicOrderCntLsb)
return 1;
}
else if (pSps1->picOrderCntType == 1)
{
if (pSps1->deltaPicOrderAlwaysZeroFlag !=
pSps2->deltaPicOrderAlwaysZeroFlag ||
pSps1->offsetForNonRefPic != pSps2->offsetForNonRefPic ||
pSps1->offsetForTopToBottomField !=
pSps2->offsetForTopToBottomField ||
pSps1->numRefFramesInPicOrderCntCycle !=
pSps2->numRefFramesInPicOrderCntCycle)
{
return 1;
}
else
{
for (i = 0; i < pSps1->numRefFramesInPicOrderCntCycle; i++)
if (pSps1->offsetForRefFrame[i] !=
pSps2->offsetForRefFrame[i])
{
return 1;
}
}
}
if (pSps1->frameCroppingFlag)
{
if (pSps1->frameCropLeftOffset != pSps2->frameCropLeftOffset ||
pSps1->frameCropRightOffset != pSps2->frameCropRightOffset ||
pSps1->frameCropTopOffset != pSps2->frameCropTopOffset ||
pSps1->frameCropBottomOffset != pSps2->frameCropBottomOffset)
{
return 1;
}
}
if (!pSps1->frameMbsOnlyFlag)
if (pSps1->mbAdaptiveFrameFieldFlag !=
pSps2->mbAdaptiveFrameFieldFlag)
return 1;
/* copy scaling matrices if used */
if (pSps1->scalingMatrixPresentFlag)
{
u32 i, j;
for (i = 0; i < 8; i++)
{
pSps2->scalingListPresent[i] = pSps1->scalingListPresent[i];
for (j = 0; j < 64; j++)
pSps2->scalingList[i][j] = pSps1->scalingList[i][j];
}
}
return 0;
}
return 1;
}

View File

@ -0,0 +1,329 @@
/*------------------------------------------------------------------------------
-- --
-- This software is confidential and proprietary and may be used --
-- only as expressly authorized by a licensing agreement from --
-- --
-- Hantro Products Oy. --
-- --
-- (C) COPYRIGHT 2006 HANTRO PRODUCTS OY --
-- ALL RIGHTS RESERVED --
-- --
-- The entire notice above must be reproduced --
-- on all copies and should not be removed. --
-- --
--------------------------------------------------------------------------------
--
-- Abstract : Decode slice data, i.e. macroblocks of a slice, from the stream
--
--------------------------------------------------------------------------------
--
-- Version control information, please leave untouched.
--
-- $RCSfile: h264hwd_slice_data.c,v $
-- $Date: 2008/10/27 12:58:51 $
-- $Revision: 1.2 $
--
------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------
1. Include headers
------------------------------------------------------------------------------*/
#include "dwl.h"
#include "h264hwd_container.h"
#include "h264hwd_slice_data.h"
#include "h264hwd_util.h"
#include "h264hwd_vlc.h"
#include "h264hwd_exports.h"
/*------------------------------------------------------------------------------
5.1 Function name: h264bsdDecodeSliceData
Functional description:
Decode one slice. Function decodes stream data, i.e. macroblocks
and possible skip_run fields. h264bsdDecodeMacroblock function is
called to handle all other macroblock related processing.
Macroblock to slice group mapping is considered when next
macroblock to process is determined (h264bsdNextMbAddress function)
map
Inputs:
pStrmData pointer to stream data structure
pStorage pointer to storage structure
currImage pointer to current processed picture, needed for
intra prediction of the macroblocks
pSliceHeader pointer to slice header of the current slice
Outputs:
currImage processed macroblocks are written to current image
pStorage mbStorage structure of each processed macroblock
is updated here
Returns:
HANTRO_OK success
HANTRO_NOK invalid stream data
------------------------------------------------------------------------------*/
u32 h264bsdDecodeSliceData(decContainer_t * pDecCont, strmData_t * pStrmData,
sliceHeader_t * pSliceHeader)
{
/* Variables */
u32 tmp;
u32 skipRun;
u32 prevSkipped;
u32 currMbAddr;
u32 moreMbs;
u32 mbCount;
i32 qpY;
macroblockLayer_t *mbLayer;
storage_t *pStorage;
DecAsicBuffers_t *pAsicBuff = NULL;
sliceStorage_t *slice;
/* Code */
ASSERT(pStrmData);
ASSERT(pSliceHeader);
ASSERT(pDecCont);
pStorage = &pDecCont->storage;
mbLayer = pStorage->mbLayer;
slice = pStorage->slice;
pAsicBuff = pDecCont->asicBuff;
currMbAddr = pSliceHeader->firstMbInSlice;
ASSERT(currMbAddr < pStorage->picSizeInMbs);
skipRun = 0;
prevSkipped = HANTRO_FALSE;
/* increment slice index, will be one for decoding of the first slice of
* the picture */
slice->sliceId++;
/* lastMbAddr stores address of the macroblock that was last successfully
* decoded, needed for error handling */
slice->lastMbAddr = 0;
mbCount = 0;
/* initial quantization parameter for the slice is obtained as the sum of
* initial QP for the picture and sliceQpDelta for the current slice */
qpY = (i32) pStorage->activePps->picInitQp + pSliceHeader->sliceQpDelta;
do
{
mbStorage_t *mb = pStorage->mb + currMbAddr;
/* primary picture and already decoded macroblock -> error */
if(!pSliceHeader->redundantPicCnt && mb->decoded)
{
ERROR_PRINT("Primary and already decoded");
return (HANTRO_NOK);
}
mb->sliceId = slice->sliceId;
if(!IS_I_SLICE(pSliceHeader->sliceType))
{
{
if(!prevSkipped)
{
tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &skipRun);
if(tmp != HANTRO_OK)
return (tmp);
if(skipRun == (pStorage->picSizeInMbs << 1) &&
pSliceHeader->frameNum == 0xF)
{
skipRun = MIN(0, pStorage->picSizeInMbs - currMbAddr);
}
/* skip_run shall be less than or equal to number of
* macroblocks left */
#ifdef HANTRO_PEDANTIC_MODE
else if(skipRun > (pStorage->picSizeInMbs - currMbAddr))
{
ERROR_PRINT("skip_run");
return (HANTRO_NOK);
}
#endif /* HANTRO_PEDANTIC_MODE */
if(skipRun)
{
/*mbPred_t *mbPred = &mbLayer->mbPred; */
prevSkipped = HANTRO_TRUE;
/*DWLmemset(&mbLayer->mbPred, 0, sizeof(mbPred_t)); */
/*DWLmemset(mbPred->remIntra4x4PredMode, 0, sizeof(mbPred->remIntra4x4PredMode)); */
/*DWLmemset(mbPred->refIdxL0, 0, sizeof(mbPred->refIdxL0)); */
/* mark current macroblock skipped */
mbLayer->mbType = P_Skip;
}
}
}
}
mbLayer->mbQpDelta = 0;
{
if(skipRun)
{
/*DEBUG_PRINT(("Skipping macroblock %d\n", currMbAddr)); */
skipRun--;
}
else
{
prevSkipped = HANTRO_FALSE;
tmp = h264bsdDecodeMacroblockLayerCavlc(pStrmData, mbLayer,
mb, pSliceHeader);
if(tmp != HANTRO_OK)
{
ERROR_PRINT("macroblock_layer");
return (tmp);
}
}
}
mbLayer->filterOffsetA = pSliceHeader->sliceAlphaC0Offset;
mbLayer->filterOffsetB = pSliceHeader->sliceBetaOffset;
mbLayer->disableDeblockingFilterIdc =
pSliceHeader->disableDeblockingFilterIdc;
pAsicBuff->currentMB = currMbAddr;
tmp = h264bsdDecodeMacroblock(pStorage, currMbAddr, &qpY, pAsicBuff);
if(tmp != HANTRO_OK)
{
ERROR_PRINT("MACRO_BLOCK");
return (tmp);
}
/* increment macroblock count only for macroblocks that were decoded
* for the first time (redundant slices) */
if(mb->decoded == 1)
mbCount++;
{
/* keep on processing as long as there is stream data left or
* processing of macroblocks to be skipped based on the last skipRun is
* not finished */
moreMbs = (h264bsdMoreRbspData(pStrmData) ||
skipRun) ? HANTRO_TRUE : HANTRO_FALSE;
}
/* lastMbAddr is only updated for intra slices (all macroblocks of
* inter slices will be lost in case of an error) */
if(IS_I_SLICE(pSliceHeader->sliceType))
slice->lastMbAddr = currMbAddr;
currMbAddr = h264bsdNextMbAddress(pStorage->sliceGroupMap,
pStorage->picSizeInMbs, currMbAddr);
/* data left in the buffer but no more macroblocks for current slice
* group -> error */
if(moreMbs && !currMbAddr)
{
ERROR_PRINT("Next mb address");
return (HANTRO_NOK);
}
}
while(moreMbs);
if((slice->numDecodedMbs + mbCount) > pStorage->picSizeInMbs)
{
ERROR_PRINT("Num decoded mbs");
return (HANTRO_NOK);
}
slice->numDecodedMbs += mbCount;
return (HANTRO_OK);
}
/*------------------------------------------------------------------------------
5.3 Function name: h264bsdMarkSliceCorrupted
Functional description:
Mark macroblocks of the slice corrupted. If lastMbAddr in the slice
storage is set -> picWidhtInMbs (or at least 10) macroblocks back
from the lastMbAddr are marked corrupted. However, if lastMbAddr
is not set -> all macroblocks of the slice are marked.
Inputs:
pStorage pointer to storage structure
firstMbInSlice address of the first macroblock in the slice, this
identifies the slice to be marked corrupted
Outputs:
pStorage mbStorage for the corrupted macroblocks updated
Returns:
none
------------------------------------------------------------------------------*/
void h264bsdMarkSliceCorrupted(storage_t * pStorage, u32 firstMbInSlice)
{
/* Variables */
u32 tmp, i;
u32 sliceId;
u32 currMbAddr;
/* Code */
ASSERT(pStorage);
ASSERT(firstMbInSlice < pStorage->picSizeInMbs);
currMbAddr = firstMbInSlice;
sliceId = pStorage->slice->sliceId;
/* DecodeSliceData sets lastMbAddr for I slices -> if it was set, go back
* MAX(picWidthInMbs, 10) macroblocks and start marking from there */
if(pStorage->slice->lastMbAddr)
{
ASSERT(pStorage->mb[pStorage->slice->lastMbAddr].sliceId == sliceId);
i = pStorage->slice->lastMbAddr - 1;
tmp = 0;
while(i > currMbAddr)
{
if(pStorage->mb[i].sliceId == sliceId)
{
tmp++;
if(tmp >= MAX(pStorage->activeSps->picWidthInMbs, 10))
break;
}
i--;
}
currMbAddr = i;
}
do
{
if((pStorage->mb[currMbAddr].sliceId == sliceId) &&
(pStorage->mb[currMbAddr].decoded))
{
pStorage->mb[currMbAddr].decoded--;
}
else
{
break;
}
currMbAddr = h264bsdNextMbAddress(pStorage->sliceGroupMap,
pStorage->picSizeInMbs, currMbAddr);
}
while(currMbAddr);
}

View File

@ -0,0 +1,599 @@
/*------------------------------------------------------------------------------
-- --
-- This software is confidential and proprietary and may be used --
-- only as expressly authorized by a licensing agreement from --
-- --
-- Hantro Products Oy. --
-- --
-- (C) COPYRIGHT 2006 HANTRO PRODUCTS OY --
-- ALL RIGHTS RESERVED --
-- --
-- The entire notice above must be reproduced --
-- on all copies and should not be removed. --
-- --
--------------------------------------------------------------------------------
--
-- Abstract : Compute macroblock to slice group map
--
--------------------------------------------------------------------------------
--
-- Version control information, please leave untouched.
--
-- $RCSfile: h264hwd_slice_group_map.c,v $
-- $Date: 2008/03/13 12:48:06 $
-- $Revision: 1.1 $
--
------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------
Table of contents
1. Include headers
2. External compiler flags
3. Module defines
4. Local function prototypes
5. Functions
DecodeInterleavedMap
DecodeDispersedMap
DecodeForegroundLeftOverMap
DecodeBoxOutMap
DecodeRasterScanMap
DecodeWipeMap
h264bsdDecodeSliceGroupMap
------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------
1. Include headers
------------------------------------------------------------------------------*/
#include "dwl.h"
#include "basetype.h"
#include "h264hwd_slice_group_map.h"
#include "h264hwd_cfg.h"
#include "h264hwd_pic_param_set.h"
#include "h264hwd_util.h"
/*------------------------------------------------------------------------------
2. External compiler flags
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
3. Module defines
------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------
4. Local function prototypes
------------------------------------------------------------------------------*/
static void DecodeInterleavedMap(
u32 *map,
u32 numSliceGroups,
u32 *runLength,
u32 picSize);
static void DecodeDispersedMap(
u32 *map,
u32 numSliceGroups,
u32 picWidth,
u32 picHeight);
static void DecodeForegroundLeftOverMap(
u32 *map,
u32 numSliceGroups,
u32 *topLeft,
u32 *bottomRight,
u32 picWidth,
u32 picHeight);
static void DecodeBoxOutMap(
u32 *map,
u32 sliceGroupChangeDirectionFlag,
u32 unitsInSliceGroup0,
u32 picWidth,
u32 picHeight);
static void DecodeRasterScanMap(
u32 *map,
u32 sliceGroupChangeDirectionFlag,
u32 sizeOfUpperLeftGroup,
u32 picSize);
static void DecodeWipeMap(
u32 *map,
u32 sliceGroupChangeDirectionFlag,
u32 sizeOfUpperLeftGroup,
u32 picWidth,
u32 picHeight);
/*------------------------------------------------------------------------------
Function: DecodeInterleavedMap
Functional description:
Function to decode interleaved slice group map type, i.e. slice
group map type 0.
Inputs:
map pointer to the map
numSliceGroups number of slice groups
runLength run_length[] values for each slice group
picSize picture size in macroblocks
Outputs:
map slice group map is stored here
Returns:
none
------------------------------------------------------------------------------*/
void DecodeInterleavedMap(
u32 *map,
u32 numSliceGroups,
u32 *runLength,
u32 picSize)
{
/* Variables */
u32 i,j, group;
/* Code */
ASSERT(map);
ASSERT(numSliceGroups >= 1 && numSliceGroups <= MAX_NUM_SLICE_GROUPS);
ASSERT(runLength);
i = 0;
do {
for (group = 0; group < numSliceGroups && i < picSize;
i += runLength[group++])
{
ASSERT(runLength[group] <= picSize);
for (j = 0; j < runLength[group] && i + j < picSize; j++)
map[i+j] = group;
}
} while (i < picSize);
}
/*------------------------------------------------------------------------------
Function: DecodeDispersedMap
Functional description:
Function to decode dispersed slice group map type, i.e. slice
group map type 1.
Inputs:
map pointer to the map
numSliceGroups number of slice groups
picWidth picture width in macroblocks
picHeight picture height in macroblocks
Outputs:
map slice group map is stored here
Returns:
none
------------------------------------------------------------------------------*/
void DecodeDispersedMap(
u32 *map,
u32 numSliceGroups,
u32 picWidth,
u32 picHeight)
{
/* Variables */
u32 i, picSize;
/* Code */
ASSERT(map);
ASSERT(numSliceGroups >= 1 && numSliceGroups <= MAX_NUM_SLICE_GROUPS);
ASSERT(picWidth);
ASSERT(picHeight);
picSize = picWidth * picHeight;
for (i = 0; i < picSize; i++)
map[i] = ((i % picWidth) + (((i / picWidth) * numSliceGroups) >> 1)) %
numSliceGroups;
}
/*------------------------------------------------------------------------------
Function: DecodeForegroundLeftOverMap
Functional description:
Function to decode foreground with left-over slice group map type,
i.e. slice group map type 2.
Inputs:
map pointer to the map
numSliceGroups number of slice groups
topLeft top_left[] values
bottomRight bottom_right[] values
picWidth picture width in macroblocks
picHeight picture height in macroblocks
Outputs:
map slice group map is stored here
Returns:
none
------------------------------------------------------------------------------*/
void DecodeForegroundLeftOverMap(
u32 *map,
u32 numSliceGroups,
u32 *topLeft,
u32 *bottomRight,
u32 picWidth,
u32 picHeight)
{
/* Variables */
u32 i,y,x,yTopLeft,yBottomRight,xTopLeft,xBottomRight, picSize;
u32 group;
/* Code */
ASSERT(map);
ASSERT(numSliceGroups >= 1 && numSliceGroups <= MAX_NUM_SLICE_GROUPS);
ASSERT(topLeft);
ASSERT(bottomRight);
ASSERT(picWidth);
ASSERT(picHeight);
picSize = picWidth * picHeight;
for (i = 0; i < picSize; i++)
map[i] = numSliceGroups - 1;
for (group = numSliceGroups - 1; group--; )
{
ASSERT( topLeft[group] <= bottomRight[group] &&
bottomRight[group] < picSize );
yTopLeft = topLeft[group] / picWidth;
xTopLeft = topLeft[group] % picWidth;
yBottomRight = bottomRight[group] / picWidth;
xBottomRight = bottomRight[group] % picWidth;
ASSERT(xTopLeft <= xBottomRight);
for (y = yTopLeft; y <= yBottomRight; y++)
for (x = xTopLeft; x <= xBottomRight; x++)
map[ y * picWidth + x ] = group;
}
}
/*------------------------------------------------------------------------------
Function: DecodeBoxOutMap
Functional description:
Function to decode box-out slice group map type, i.e. slice group
map type 3.
Inputs:
map pointer to the map
sliceGroupChangeDirectionFlag slice_group_change_direction_flag
unitsInSliceGroup0 mbs on slice group 0
picWidth picture width in macroblocks
picHeight picture height in macroblocks
Outputs:
map slice group map is stored here
Returns:
none
------------------------------------------------------------------------------*/
void DecodeBoxOutMap(
u32 *map,
u32 sliceGroupChangeDirectionFlag,
u32 unitsInSliceGroup0,
u32 picWidth,
u32 picHeight)
{
/* Variables */
u32 i, k, picSize;
i32 x, y, xDir, yDir, leftBound, topBound, rightBound, bottomBound;
u32 mapUnitVacant;
/* Code */
ASSERT(map);
ASSERT(picWidth);
ASSERT(picHeight);
picSize = picWidth * picHeight;
ASSERT(unitsInSliceGroup0 <= picSize);
for (i = 0; i < picSize; i++)
map[i] = 1;
x = (picWidth - (u32)sliceGroupChangeDirectionFlag) >> 1;
y = (picHeight - (u32)sliceGroupChangeDirectionFlag) >> 1;
leftBound = x;
topBound = y;
rightBound = x;
bottomBound = y;
xDir = (i32)sliceGroupChangeDirectionFlag - 1;
yDir = (i32)sliceGroupChangeDirectionFlag;
for (k = 0; k < unitsInSliceGroup0; k += mapUnitVacant ? 1 : 0)
{
mapUnitVacant = (map[ (u32)y * picWidth + (u32)x ] == 1) ? HANTRO_TRUE : HANTRO_FALSE;
if (mapUnitVacant)
map[ (u32)y * picWidth + (u32)x ] = 0;
if (xDir == -1 && x == leftBound)
{
leftBound = MAX(leftBound - 1, 0);
x = leftBound;
xDir = 0;
yDir = 2 * (i32)sliceGroupChangeDirectionFlag - 1;
}
else if (xDir == 1 && x == rightBound)
{
rightBound = MIN(rightBound + 1, (i32)picWidth - 1);
x = rightBound;
xDir = 0;
yDir = 1 - 2 * (i32)sliceGroupChangeDirectionFlag;
}
else if (yDir == -1 && y == topBound)
{
topBound = MAX(topBound - 1, 0);
y = topBound;
xDir = 1 - 2 * (i32)sliceGroupChangeDirectionFlag;
yDir = 0;
}
else if (yDir == 1 && y == bottomBound)
{
bottomBound = MIN(bottomBound + 1, (i32)picHeight - 1);
y = bottomBound;
xDir = 2 * (i32)sliceGroupChangeDirectionFlag - 1;
yDir = 0;
}
else
{
x += xDir;
y += yDir;
}
}
}
/*------------------------------------------------------------------------------
Function: DecodeRasterScanMap
Functional description:
Function to decode raster scan slice group map type, i.e. slice
group map type 4.
Inputs:
map pointer to the map
sliceGroupChangeDirectionFlag slice_group_change_direction_flag
sizeOfUpperLeftGroup mbs in upperLeftGroup
picSize picture size in macroblocks
Outputs:
map slice group map is stored here
Returns:
none
------------------------------------------------------------------------------*/
void DecodeRasterScanMap(
u32 *map,
u32 sliceGroupChangeDirectionFlag,
u32 sizeOfUpperLeftGroup,
u32 picSize)
{
/* Variables */
u32 i;
/* Code */
ASSERT(map);
ASSERT(picSize);
ASSERT(sizeOfUpperLeftGroup <= picSize);
for (i = 0; i < picSize; i++)
if (i < sizeOfUpperLeftGroup)
map[i] = (u32)sliceGroupChangeDirectionFlag;
else
map[i] = 1 - (u32)sliceGroupChangeDirectionFlag;
}
/*------------------------------------------------------------------------------
Function: DecodeWipeMap
Functional description:
Function to decode wipe slice group map type, i.e. slice group map
type 5.
Inputs:
sliceGroupChangeDirectionFlag slice_group_change_direction_flag
sizeOfUpperLeftGroup mbs in upperLeftGroup
picWidth picture width in macroblocks
picHeight picture height in macroblocks
Outputs:
map slice group map is stored here
Returns:
none
------------------------------------------------------------------------------*/
void DecodeWipeMap(
u32 *map,
u32 sliceGroupChangeDirectionFlag,
u32 sizeOfUpperLeftGroup,
u32 picWidth,
u32 picHeight)
{
/* Variables */
u32 i,j,k;
/* Code */
ASSERT(map);
ASSERT(picWidth);
ASSERT(picHeight);
ASSERT(sizeOfUpperLeftGroup <= picWidth * picHeight);
k = 0;
for (j = 0; j < picWidth; j++)
for (i = 0; i < picHeight; i++)
if (k++ < sizeOfUpperLeftGroup)
map[ i * picWidth + j ] = (u32)sliceGroupChangeDirectionFlag;
else
map[ i * picWidth + j ] = 1 -
(u32)sliceGroupChangeDirectionFlag;
}
/*------------------------------------------------------------------------------
Function: h264bsdDecodeSliceGroupMap
Functional description:
Function to decode macroblock to slice group map. Construction
of different slice group map types is handled by separate
functions defined above. See standard for details how slice group
maps are computed.
Inputs:
pps active picture parameter set
sliceGroupChangeCycle slice_group_change_cycle
picWidth picture width in macroblocks
picHeight picture height in macroblocks
Outputs:
map slice group map is stored here
Returns:
none
------------------------------------------------------------------------------*/
void h264bsdDecodeSliceGroupMap(
u32 *map,
picParamSet_t *pps,
u32 sliceGroupChangeCycle,
u32 picWidth,
u32 picHeight)
{
/* Variables */
u32 i, picSize, unitsInSliceGroup0 = 0, sizeOfUpperLeftGroup = 0;
/* Code */
ASSERT(map);
ASSERT(pps);
ASSERT(picWidth);
ASSERT(picHeight);
ASSERT(pps->sliceGroupMapType < 7);
picSize = picWidth * picHeight;
/* just one slice group -> all macroblocks belong to group 0 */
if (pps->numSliceGroups == 1)
{
(void) DWLmemset(map, 0, picSize * sizeof(u32));
return;
}
if (pps->sliceGroupMapType > 2 && pps->sliceGroupMapType < 6)
{
ASSERT(pps->sliceGroupChangeRate &&
pps->sliceGroupChangeRate <= picSize);
unitsInSliceGroup0 =
MIN(sliceGroupChangeCycle * pps->sliceGroupChangeRate, picSize);
if (pps->sliceGroupMapType == 4 || pps->sliceGroupMapType == 5)
sizeOfUpperLeftGroup = pps->sliceGroupChangeDirectionFlag ?
(picSize - unitsInSliceGroup0) : unitsInSliceGroup0;
}
switch (pps->sliceGroupMapType)
{
case 0:
DecodeInterleavedMap(map, pps->numSliceGroups,
pps->runLength, picSize);
break;
case 1:
DecodeDispersedMap(map, pps->numSliceGroups, picWidth,
picHeight);
break;
case 2:
DecodeForegroundLeftOverMap(map, pps->numSliceGroups,
pps->topLeft, pps->bottomRight, picWidth, picHeight);
break;
case 3:
DecodeBoxOutMap(map, pps->sliceGroupChangeDirectionFlag,
unitsInSliceGroup0, picWidth, picHeight);
break;
case 4:
DecodeRasterScanMap(map,
pps->sliceGroupChangeDirectionFlag, sizeOfUpperLeftGroup,
picSize);
break;
case 5:
DecodeWipeMap(map, pps->sliceGroupChangeDirectionFlag,
sizeOfUpperLeftGroup, picWidth, picHeight);
break;
default:
ASSERT(pps->sliceGroupId);
for (i = 0; i < picSize; i++)
{
ASSERT(pps->sliceGroupId[i] < pps->numSliceGroups);
map[i] = pps->sliceGroupId[i];
}
break;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,977 @@
/*------------------------------------------------------------------------------
-- --
-- This software is confidential and proprietary and may be used --
-- only as expressly authorized by a licensing agreement from --
-- --
-- Hantro Products Oy. --
-- --
-- (C) COPYRIGHT 2006 HANTRO PRODUCTS OY --
-- ALL RIGHTS RESERVED --
-- --
-- The entire notice above must be reproduced --
-- on all copies and should not be removed. --
-- --
--------------------------------------------------------------------------------
--
-- Abstract : Storage handling functionality
--
--------------------------------------------------------------------------------
--
-- Version control information, please leave untouched.
--
-- $RCSfile: h264hwd_storage.c,v $
-- $Date: 2010/01/12 07:06:02 $
-- $Revision: 1.13 $
--
------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------
1. Include headers
------------------------------------------------------------------------------*/
#include "h264hwd_storage.h"
#include "h264hwd_util.h"
#include "h264hwd_neighbour.h"
#include "h264hwd_slice_group_map.h"
#include "h264hwd_dpb.h"
#include "h264hwd_nal_unit.h"
#include "h264hwd_slice_header.h"
#include "h264hwd_seq_param_set.h"
#include "dwl.h"
/*------------------------------------------------------------------------------
2. External compiler flags
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
3. Module defines
------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------
4. Local function prototypes
------------------------------------------------------------------------------*/
static u32 CheckPps(picParamSet_t * pps, seqParamSet_t * sps);
/*------------------------------------------------------------------------------
Function name: h264bsdInitStorage
Functional description:
Initialize storage structure. Sets contents of the storage to '0'
except for the active parameter set ids, which are initialized
to invalid values.
Inputs:
Outputs:
pStorage initialized data stored here
Returns:
none
------------------------------------------------------------------------------*/
void h264bsdInitStorage(storage_t * pStorage)
{
/* Variables */
/* Code */
ASSERT(pStorage);
(void) DWLmemset(pStorage, 0, sizeof(storage_t));
pStorage->activeSpsId = MAX_NUM_SEQ_PARAM_SETS;
pStorage->activePpsId = MAX_NUM_PIC_PARAM_SETS;
pStorage->oldSpsId = MAX_NUM_SEQ_PARAM_SETS;
pStorage->aub->firstCallFlag = HANTRO_TRUE;
}
/*------------------------------------------------------------------------------
Function: h264bsdStoreSeqParamSet
Functional description:
Store sequence parameter set into the storage. If active SPS is
overwritten -> check if contents changes and if it does, set
parameters to force reactivation of parameter sets
Inputs:
pStorage pointer to storage structure
pSeqParamSet pointer to param set to be stored
Outputs:
none
Returns:
HANTRO_OK success
MEMORY_ALLOCATION_ERROR failure in memory allocation
------------------------------------------------------------------------------*/
u32 h264bsdStoreSeqParamSet(storage_t * pStorage, seqParamSet_t * pSeqParamSet)
{
/* Variables */
u32 id;
/* Code */
ASSERT(pStorage);
ASSERT(pSeqParamSet);
ASSERT(pSeqParamSet->seqParameterSetId < MAX_NUM_SEQ_PARAM_SETS);
id = pSeqParamSet->seqParameterSetId;
/* seq parameter set with id not used before -> allocate memory */
if(pStorage->sps[id] == NULL)
{
ALLOCATE(pStorage->sps[id], 1, seqParamSet_t);
if(pStorage->sps[id] == NULL)
return (MEMORY_ALLOCATION_ERROR);
}
/* sequence parameter set with id equal to id of active sps */
else if(id == pStorage->activeSpsId)
{
/* if seq parameter set contents changes
* -> overwrite and re-activate when next IDR picture decoded
* ids of active param sets set to invalid values to force
* re-activation. Memories allocated for old sps freed
* otherwise free memeries allocated for just decoded sps and
* continue */
if(h264bsdCompareSeqParamSets(pSeqParamSet, pStorage->activeSps) != 0)
{
FREE(pStorage->sps[id]->offsetForRefFrame);
FREE(pStorage->sps[id]->vuiParameters);
pStorage->activeSpsId = MAX_NUM_SEQ_PARAM_SETS + 1;
pStorage->activePpsId = MAX_NUM_PIC_PARAM_SETS + 1;
pStorage->activeSps = NULL;
pStorage->activePps = NULL;
}
else
{
FREE(pSeqParamSet->offsetForRefFrame);
FREE(pSeqParamSet->vuiParameters);
return (HANTRO_OK);
}
}
/* overwrite seq param set other than active one -> free memories
* allocated for old param set */
else
{
FREE(pStorage->sps[id]->offsetForRefFrame);
FREE(pStorage->sps[id]->vuiParameters);
}
*pStorage->sps[id] = *pSeqParamSet;
return (HANTRO_OK);
}
/*------------------------------------------------------------------------------
Function: h264bsdStorePicParamSet
Functional description:
Store picture parameter set into the storage. If active PPS is
overwritten -> check if active SPS changes and if it does -> set
parameters to force reactivation of parameter sets
Inputs:
pStorage pointer to storage structure
pPicParamSet pointer to param set to be stored
Outputs:
none
Returns:
HANTRO_OK success
MEMORY_ALLOCATION_ERROR failure in memory allocation
------------------------------------------------------------------------------*/
void h264bsdModifyScalingLists(storage_t *pStorage, picParamSet_t *pPicParamSet)
{
u32 i;
seqParamSet_t *sps;
sps = pStorage->sps[pPicParamSet->seqParameterSetId];
/* SPS not yet decoded -> cannot copy */
/* TODO: set flag to handle "missing" SPS lists properly */
if (sps == NULL)
return;
if (!pPicParamSet->scalingMatrixPresentFlag &&
sps->scalingMatrixPresentFlag)
{
pPicParamSet->scalingMatrixPresentFlag = 1;
(void)DWLmemcpy(pPicParamSet->scalingList, sps->scalingList,
sizeof(sps->scalingList));
}
else if (sps->scalingMatrixPresentFlag)
{
if (!pPicParamSet->scalingListPresent[0])
{
/* we trust our memcpy */
(void)DWLmemcpy(pPicParamSet->scalingList[0], sps->scalingList[0],
16*sizeof(u8));
for (i = 1; i < 3; i++)
if (!pPicParamSet->scalingListPresent[i])
(void)DWLmemcpy(pPicParamSet->scalingList[i],
pPicParamSet->scalingList[i-1],
16*sizeof(u8));
}
if (!pPicParamSet->scalingListPresent[3])
{
(void)DWLmemcpy(pPicParamSet->scalingList[3], sps->scalingList[3],
16*sizeof(u8));
for (i = 4; i < 6; i++)
if (!pPicParamSet->scalingListPresent[i])
(void)DWLmemcpy(pPicParamSet->scalingList[i],
pPicParamSet->scalingList[i-1],
16*sizeof(u8));
}
for (i = 6; i < 8; i++)
if (!pPicParamSet->scalingListPresent[i])
(void)DWLmemcpy(pPicParamSet->scalingList[i], sps->scalingList[i],
64*sizeof(u8));
}
}
u32 h264bsdStorePicParamSet(storage_t * pStorage, picParamSet_t * pPicParamSet)
{
/* Variables */
u32 id;
/* Code */
ASSERT(pStorage);
ASSERT(pPicParamSet);
ASSERT(pPicParamSet->picParameterSetId < MAX_NUM_PIC_PARAM_SETS);
ASSERT(pPicParamSet->seqParameterSetId < MAX_NUM_SEQ_PARAM_SETS);
id = pPicParamSet->picParameterSetId;
/* pic parameter set with id not used before -> allocate memory */
if(pStorage->pps[id] == NULL)
{
ALLOCATE(pStorage->pps[id], 1, picParamSet_t);
if(pStorage->pps[id] == NULL)
return (MEMORY_ALLOCATION_ERROR);
}
/* picture parameter set with id equal to id of active pps */
else if(id == pStorage->activePpsId)
{
/* check whether seq param set changes, force re-activation of
* param set if it does. Set activeSpsId to invalid value to
* accomplish this */
if(pPicParamSet->seqParameterSetId != pStorage->activeSpsId)
{
pStorage->activePpsId = MAX_NUM_PIC_PARAM_SETS + 1;
}
/* free memories allocated for old param set */
FREE(pStorage->pps[id]->runLength);
FREE(pStorage->pps[id]->topLeft);
FREE(pStorage->pps[id]->bottomRight);
FREE(pStorage->pps[id]->sliceGroupId);
}
/* overwrite pic param set other than active one -> free memories
* allocated for old param set */
else
{
FREE(pStorage->pps[id]->runLength);
FREE(pStorage->pps[id]->topLeft);
FREE(pStorage->pps[id]->bottomRight);
FREE(pStorage->pps[id]->sliceGroupId);
}
/* Modify scaling_lists if necessary */
h264bsdModifyScalingLists(pStorage, pPicParamSet);
*pStorage->pps[id] = *pPicParamSet;
return (HANTRO_OK);
}
/*------------------------------------------------------------------------------
Function: h264bsdActivateParamSets
Functional description:
Activate certain SPS/PPS combination. This function shall be
called in the beginning of each picture. Picture parameter set
can be changed as wanted, but sequence parameter set may only be
changed when the starting picture is an IDR picture.
When new SPS is activated the function allocates memory for
macroblock storages and slice group map and (re-)initializes the
decoded picture buffer. If this is not the first activation the old
allocations are freed and FreeDpb called before new allocations.
Inputs:
pStorage pointer to storage data structure
ppsId identifies the PPS to be activated, SPS id obtained
from the PPS
isIdr flag to indicate if the picture is an IDR picture
Outputs:
none
Returns:
HANTRO_OK success
HANTRO_NOK non-existing or invalid param set combination,
trying to change SPS with non-IDR picture
MEMORY_ALLOCATION_ERROR failure in memory allocation
------------------------------------------------------------------------------*/
u32 h264bsdActivateParamSets(storage_t * pStorage, u32 ppsId, u32 isIdr)
{
u32 tmp;
ASSERT(pStorage);
ASSERT(ppsId < MAX_NUM_PIC_PARAM_SETS);
/* check that pps and corresponding sps exist */
if((pStorage->pps[ppsId] == NULL) ||
(pStorage->sps[pStorage->pps[ppsId]->seqParameterSetId] == NULL))
{
return (HANTRO_NOK);
}
/* check that pps parameters do not violate picture size constraints */
tmp = CheckPps(pStorage->pps[ppsId],
pStorage->sps[pStorage->pps[ppsId]->seqParameterSetId]);
if(tmp != HANTRO_OK)
return (tmp);
/* first activation */
if(pStorage->activePpsId == MAX_NUM_PIC_PARAM_SETS)
{
pStorage->activePpsId = ppsId;
pStorage->activePps = pStorage->pps[ppsId];
pStorage->activeSpsId = pStorage->activePps->seqParameterSetId;
pStorage->activeSps = pStorage->sps[pStorage->activeSpsId];
}
else if(ppsId != pStorage->activePpsId)
{
/* sequence parameter set shall not change but before an IDR picture */
if(pStorage->pps[ppsId]->seqParameterSetId != pStorage->activeSpsId)
{
DEBUG_PRINT(("SEQ PARAM SET CHANGING...\n"));
if(isIdr)
{
pStorage->activePpsId = ppsId;
pStorage->activePps = pStorage->pps[ppsId];
pStorage->activeSpsId = pStorage->activePps->seqParameterSetId;
pStorage->activeSps = pStorage->sps[pStorage->activeSpsId];
}
else
{
DEBUG_PRINT(("TRYING TO CHANGE SPS IN NON-IDR SLICE\n"));
return (HANTRO_NOK);
}
}
else
{
pStorage->activePpsId = ppsId;
pStorage->activePps = pStorage->pps[ppsId];
}
}
return (HANTRO_OK);
}
/*------------------------------------------------------------------------------
Function: h264bsdResetStorage
Functional description:
Reset contents of the storage. This should be called before
processing of new image is started.
Inputs:
pStorage pointer to storage structure
Outputs:
none
Returns:
none
------------------------------------------------------------------------------*/
void h264bsdResetStorage(storage_t * pStorage)
{
/* Variables */
u32 i;
/* Code */
ASSERT(pStorage);
pStorage->slice->numDecodedMbs = 0;
pStorage->slice->sliceId = 0;
#ifdef FFWD_WORKAROUND
pStorage->prevIdrPicReady = HANTRO_FALSE;
#endif /* FFWD_WORKAROUND */
if(pStorage->mb != NULL)
{
for(i = 0; i < pStorage->picSizeInMbs; i++)
{
pStorage->mb[i].sliceId = 0;
pStorage->mb[i].decoded = 0;
}
}
}
/*------------------------------------------------------------------------------
Function: h264bsdIsStartOfPicture
Functional description:
Determine if the decoder is in the start of a picture. This
information is needed to decide if h264bsdActivateParamSets and
h264bsdCheckGapsInFrameNum functions should be called. Function
considers that new picture is starting if no slice headers
have been successfully decoded for the current access unit.
Inputs:
pStorage pointer to storage structure
Outputs:
none
Returns:
HANTRO_TRUE new picture is starting
HANTRO_FALSE not starting
------------------------------------------------------------------------------*/
u32 h264bsdIsStartOfPicture(storage_t * pStorage)
{
/* Variables */
/* Code */
if(pStorage->validSliceInAccessUnit == HANTRO_FALSE)
return (HANTRO_TRUE);
else
return (HANTRO_FALSE);
}
/*------------------------------------------------------------------------------
Function: h264bsdIsEndOfPicture
Functional description:
Determine if the decoder is in the end of a picture. This
information is needed to determine when deblocking filtering
and reference picture marking processes should be performed.
If the decoder is processing primary slices the return value
is determined by checking the value of numDecodedMbs in the
storage. On the other hand, if the decoder is processing
redundant slices the numDecodedMbs may not contain valid
informationa and each macroblock has to be checked separately.
Inputs:
pStorage pointer to storage structure
Outputs:
none
Returns:
HANTRO_TRUE end of picture
HANTRO_FALSE noup
------------------------------------------------------------------------------*/
u32 h264bsdIsEndOfPicture(storage_t * pStorage)
{
/* Variables */
u32 i, tmp;
/* Code */
ASSERT(pStorage != NULL);
/* primary picture */
if(!pStorage->sliceHeader[0].redundantPicCnt)
{
if(pStorage->slice->numDecodedMbs == pStorage->picSizeInMbs)
return (HANTRO_TRUE);
}
else
{
ASSERT(pStorage->mb != NULL);
for(i = 0, tmp = 0; i < pStorage->picSizeInMbs; i++)
tmp += pStorage->mb[i].decoded ? 1 : 0;
if(tmp == pStorage->picSizeInMbs)
return (HANTRO_TRUE);
}
return (HANTRO_FALSE);
}
/*------------------------------------------------------------------------------
Function: h264bsdComputeSliceGroupMap
Functional description:
Compute slice group map. Just call h264bsdDecodeSliceGroupMap with
appropriate parameters.
Inputs:
pStorage pointer to storage structure
sliceGroupChangeCycle
Outputs:
none
Returns:
none
------------------------------------------------------------------------------*/
void h264bsdComputeSliceGroupMap(storage_t * pStorage,
u32 sliceGroupChangeCycle)
{
/* Variables */
/* Code */
h264bsdDecodeSliceGroupMap(pStorage->sliceGroupMap,
pStorage->activePps, sliceGroupChangeCycle,
pStorage->activeSps->picWidthInMbs,
pStorage->activeSps->picHeightInMbs);
}
/*------------------------------------------------------------------------------
Function: h264bsdCheckAccessUnitBoundary
Functional description:
Check if next NAL unit starts a new access unit. Following
conditions specify start of a new access unit:
-NAL unit types 6-11, 13-18 (e.g. SPS, PPS)
following conditions checked only for slice NAL units, values
compared to ones obtained from previous slice:
-NAL unit type differs (slice / IDR slice)
-frame_num differs
-nal_ref_idc differs and one of the values is 0
-POC information differs
-both are IDR slices and idr_pic_id differs
Inputs:
strm pointer to stream data structure
nuNext pointer to NAL unit structure
storage pointer to storage structure
Outputs:
accessUnitBoundaryFlag the result is stored here, HANTRO_TRUE for
access unit boundary, HANTRO_FALSE otherwise
Returns:
HANTRO_OK success
HANTRO_NOK failure, invalid stream data
PARAM_SET_ERROR invalid param set usage
------------------------------------------------------------------------------*/
u32 h264bsdCheckAccessUnitBoundary(strmData_t * strm,
nalUnit_t * nuNext,
storage_t * storage,
u32 * accessUnitBoundaryFlag)
{
/* Variables */
u32 tmp, ppsId, frameNum, idrPicId, picOrderCntLsb;
u32 fieldPicFlag = 0, bottomFieldFlag = 0;
i32 deltaPicOrderCntBottom, deltaPicOrderCnt[2];
#ifdef FFWD_WORKAROUND
u32 firstMbInSlice = 0;
u32 redundantPicCnt = 0;
#endif /* FFWD_WORKAROUND */
seqParamSet_t *sps;
picParamSet_t *pps;
/* Code */
ASSERT(strm);
ASSERT(nuNext);
ASSERT(storage);
ASSERT(storage->sps);
ASSERT(storage->pps);
DEBUG_PRINT(("h264bsdCheckAccessUnitBoundary #\n"));
/* initialize default output to HANTRO_FALSE */
*accessUnitBoundaryFlag = HANTRO_FALSE;
/* TODO field_pic_flag, bottom_field_flag */
if(((nuNext->nalUnitType > 5) && (nuNext->nalUnitType < 12)) ||
((nuNext->nalUnitType > 12) && (nuNext->nalUnitType <= 18)))
{
*accessUnitBoundaryFlag = HANTRO_TRUE;
return (HANTRO_OK);
}
else if(nuNext->nalUnitType != NAL_CODED_SLICE &&
nuNext->nalUnitType != NAL_CODED_SLICE_IDR)
{
return (HANTRO_OK);
}
/* check if this is the very first call to this function */
if(storage->aub->firstCallFlag)
{
*accessUnitBoundaryFlag = HANTRO_TRUE;
storage->aub->firstCallFlag = HANTRO_FALSE;
}
/* get picture parameter set id */
tmp = h264bsdCheckPpsId(strm, &ppsId);
if(tmp != HANTRO_OK)
return (tmp);
/* store sps and pps in separate pointers just to make names shorter */
pps = storage->pps[ppsId];
if(pps == NULL || storage->sps[pps->seqParameterSetId] == NULL ||
(storage->activeSpsId != MAX_NUM_SEQ_PARAM_SETS &&
pps->seqParameterSetId != storage->activeSpsId &&
nuNext->nalUnitType != NAL_CODED_SLICE_IDR))
return (PARAM_SET_ERROR);
sps = storage->sps[pps->seqParameterSetId];
if(storage->aub->nuPrev->nalRefIdc != nuNext->nalRefIdc &&
(storage->aub->nuPrev->nalRefIdc == 0 || nuNext->nalRefIdc == 0))
{
*accessUnitBoundaryFlag = HANTRO_TRUE;
storage->aub->newPicture = HANTRO_TRUE;
}
else
storage->aub->newPicture = HANTRO_FALSE;
if((storage->aub->nuPrev->nalUnitType == NAL_CODED_SLICE_IDR &&
nuNext->nalUnitType != NAL_CODED_SLICE_IDR) ||
(storage->aub->nuPrev->nalUnitType != NAL_CODED_SLICE_IDR &&
nuNext->nalUnitType == NAL_CODED_SLICE_IDR))
*accessUnitBoundaryFlag = HANTRO_TRUE;
tmp = h264bsdCheckFrameNum(strm, sps->maxFrameNum, &frameNum);
if(tmp != HANTRO_OK)
return (HANTRO_NOK);
if(storage->aub->prevFrameNum != frameNum)
{
storage->aub->prevFrameNum = frameNum;
*accessUnitBoundaryFlag = HANTRO_TRUE;
}
tmp = h264bsdCheckFieldPicFlag(strm, sps->maxFrameNum, nuNext->nalUnitType,
!sps->frameMbsOnlyFlag, &fieldPicFlag);
if (fieldPicFlag != storage->aub->prevFieldPicFlag)
{
storage->aub->prevFieldPicFlag = fieldPicFlag;
*accessUnitBoundaryFlag = HANTRO_TRUE;
}
tmp = h264bsdCheckBottomFieldFlag(strm, sps->maxFrameNum,
nuNext->nalUnitType,
!sps->frameMbsOnlyFlag, &bottomFieldFlag);
DEBUG_PRINT(("FIELD %d bottom %d\n",fieldPicFlag, bottomFieldFlag));
if (bottomFieldFlag != storage->aub->prevBottomFieldFlag)
{
storage->aub->prevBottomFieldFlag = bottomFieldFlag;
*accessUnitBoundaryFlag = HANTRO_TRUE;
}
if(nuNext->nalUnitType == NAL_CODED_SLICE_IDR)
{
tmp = h264bsdCheckIdrPicId(strm, sps->maxFrameNum,
nuNext->nalUnitType, !sps->frameMbsOnlyFlag, &idrPicId);
if(tmp != HANTRO_OK)
return (HANTRO_NOK);
if(storage->aub->nuPrev->nalUnitType == NAL_CODED_SLICE_IDR &&
storage->aub->prevIdrPicId != idrPicId)
*accessUnitBoundaryFlag = HANTRO_TRUE;
#ifdef FFWD_WORKAROUND
/* FFWD workaround */
if(!*accessUnitBoundaryFlag )
{
/* if prev IDR pic ready and first MB is zero */
tmp = h264bsdCheckFirstMbInSlice( strm,
nuNext->nalUnitType,
&firstMbInSlice );
if( tmp != HANTRO_OK )
return (HANTRO_NOK);
if(storage->prevIdrPicReady && firstMbInSlice == 0)
{
/* Just to make sure, check that next IDR is not marked as
* redundant */
tmp = h264bsdCheckRedundantPicCnt( strm,
sps, pps, nuNext->nalUnitType,
&redundantPicCnt );
if( tmp != HANTRO_OK )
return (HANTRO_NOK);
if( redundantPicCnt == 0 )
{
*accessUnitBoundaryFlag = HANTRO_TRUE;
}
}
}
#endif /* FFWD_WORKAROUND */
storage->aub->prevIdrPicId = idrPicId;
}
if(sps->picOrderCntType == 0)
{
tmp = h264bsdCheckPicOrderCntLsb(strm, sps, nuNext->nalUnitType,
&picOrderCntLsb);
if(tmp != HANTRO_OK)
return (HANTRO_NOK);
if(storage->aub->prevPicOrderCntLsb != picOrderCntLsb)
{
storage->aub->prevPicOrderCntLsb = picOrderCntLsb;
*accessUnitBoundaryFlag = HANTRO_TRUE;
}
if(pps->picOrderPresentFlag)
{
tmp = h264bsdCheckDeltaPicOrderCntBottom(strm, sps,
nuNext->nalUnitType,
&deltaPicOrderCntBottom);
if(tmp != HANTRO_OK)
return (tmp);
if(storage->aub->prevDeltaPicOrderCntBottom !=
deltaPicOrderCntBottom)
{
storage->aub->prevDeltaPicOrderCntBottom =
deltaPicOrderCntBottom;
*accessUnitBoundaryFlag = HANTRO_TRUE;
}
}
}
else if(sps->picOrderCntType == 1 && !sps->deltaPicOrderAlwaysZeroFlag)
{
tmp = h264bsdCheckDeltaPicOrderCnt(strm, sps, nuNext->nalUnitType,
pps->picOrderPresentFlag,
deltaPicOrderCnt);
if(tmp != HANTRO_OK)
return (tmp);
if(storage->aub->prevDeltaPicOrderCnt[0] != deltaPicOrderCnt[0])
{
storage->aub->prevDeltaPicOrderCnt[0] = deltaPicOrderCnt[0];
*accessUnitBoundaryFlag = HANTRO_TRUE;
}
if(pps->picOrderPresentFlag)
if(storage->aub->prevDeltaPicOrderCnt[1] != deltaPicOrderCnt[1])
{
storage->aub->prevDeltaPicOrderCnt[1] = deltaPicOrderCnt[1];
*accessUnitBoundaryFlag = HANTRO_TRUE;
}
}
*storage->aub->nuPrev = *nuNext;
return (HANTRO_OK);
}
/*------------------------------------------------------------------------------
Function: CheckPps
Functional description:
Check picture parameter set. Contents of the picture parameter
set information that depends on the image dimensions is checked
against the dimensions in the sps.
Inputs:
pps pointer to picture paramter set
sps pointer to sequence parameter set
Outputs:
none
Returns:
HANTRO_OK everything ok
HANTRO_NOK invalid data in picture parameter set
------------------------------------------------------------------------------*/
u32 CheckPps(picParamSet_t * pps, seqParamSet_t * sps)
{
u32 i;
u32 picSize;
picSize = sps->picWidthInMbs * sps->picHeightInMbs;
/* check slice group params */
if(pps->numSliceGroups > 1)
{
/* no FMO supported if stream may contain interlaced stuff */
if (sps->frameMbsOnlyFlag == 0)
return(HANTRO_NOK);
if(pps->sliceGroupMapType == 0)
{
ASSERT(pps->runLength);
for(i = 0; i < pps->numSliceGroups; i++)
{
if(pps->runLength[i] > picSize)
return (HANTRO_NOK);
}
}
else if(pps->sliceGroupMapType == 2)
{
ASSERT(pps->topLeft);
ASSERT(pps->bottomRight);
for(i = 0; i < pps->numSliceGroups - 1; i++)
{
if(pps->topLeft[i] > pps->bottomRight[i] ||
pps->bottomRight[i] >= picSize)
return (HANTRO_NOK);
if((pps->topLeft[i] % sps->picWidthInMbs) >
(pps->bottomRight[i] % sps->picWidthInMbs))
return (HANTRO_NOK);
}
}
else if(pps->sliceGroupMapType > 2 && pps->sliceGroupMapType < 6)
{
if(pps->sliceGroupChangeRate > picSize)
return (HANTRO_NOK);
}
else if (pps->sliceGroupMapType == 6 &&
pps->picSizeInMapUnits < picSize)
return(HANTRO_NOK);
}
return (HANTRO_OK);
}
/*------------------------------------------------------------------------------
Function: h264bsdValidParamSets
Functional description:
Check if any valid SPS/PPS combination exists in the storage.
Function tries each PPS in the buffer and checks if corresponding
SPS exists and calls CheckPps to determine if the PPS conforms
to image dimensions of the SPS.
Inputs:
pStorage pointer to storage structure
Outputs:
HANTRO_OK there is at least one valid combination
HANTRO_NOK no valid combinations found
------------------------------------------------------------------------------*/
u32 h264bsdValidParamSets(storage_t * pStorage)
{
/* Variables */
u32 i;
/* Code */
ASSERT(pStorage);
for(i = 0; i < MAX_NUM_PIC_PARAM_SETS; i++)
{
if(pStorage->pps[i] &&
pStorage->sps[pStorage->pps[i]->seqParameterSetId] &&
CheckPps(pStorage->pps[i],
pStorage->sps[pStorage->pps[i]->seqParameterSetId]) ==
HANTRO_OK)
{
return (HANTRO_OK);
}
}
return (HANTRO_NOK);
}
/*------------------------------------------------------------------------------
Function name : h264bsdAllocateSwResources
Description :
Return type : u32
Argument : const void *dwl
Argument : storage_t * pStorage
Argument : u32 isHighSupported
------------------------------------------------------------------------------*/
u32 h264bsdAllocateSwResources(const void *dwl, storage_t * pStorage,
u32 isHighSupported)
{
u32 tmp;
u32 noReorder;
const seqParamSet_t *pSps = pStorage->activeSps;
pStorage->picSizeInMbs = pSps->picWidthInMbs * pSps->picHeightInMbs;
pStorage->currImage->width = pSps->picWidthInMbs;
pStorage->currImage->height = pSps->picHeightInMbs;
/* dpb output reordering disabled if
* 1) application set noReordering flag
* 2) POC type equal to 2
* 3) num_reorder_frames in vui equal to 0 */
if(pStorage->noReordering ||
pSps->picOrderCntType == 2 ||
(pSps->vuiParametersPresentFlag &&
pSps->vuiParameters->bitstreamRestrictionFlag &&
!pSps->vuiParameters->numReorderFrames))
noReorder = HANTRO_TRUE;
else
noReorder = HANTRO_FALSE;
/* note that calling ResetDpb here results in losing all
* pictures currently in DPB -> nothing will be output from
* the buffer even if noOutputOfPriorPicsFlag is HANTRO_FALSE */
tmp = h264bsdResetDpb(dwl, pStorage->dpb, pStorage->picSizeInMbs,
pSps->maxDpbSize, pSps->numRefFrames,
pSps->maxFrameNum, noReorder, pStorage->useSmoothing,
pSps->monoChrome, isHighSupported,
pStorage->enable2ndChroma && !pSps->monoChrome);
if(tmp != HANTRO_OK)
return (tmp);
return HANTRO_OK;
}

View File

@ -0,0 +1,380 @@
/*------------------------------------------------------------------------------
-- --
-- This software is confidential and proprietary and may be used --
-- only as expressly authorized by a licensing agreement from --
-- --
-- Hantro Products Oy. --
-- --
-- (C) COPYRIGHT 2006 HANTRO PRODUCTS OY --
-- ALL RIGHTS RESERVED --
-- --
-- The entire notice above must be reproduced --
-- on all copies and should not be removed. --
-- --
--------------------------------------------------------------------------------
--
-- Abstract : Stream buffer handling
--
--------------------------------------------------------------------------------
--
-- Version control information, please leave untouched.
--
-- $RCSfile: h264hwd_stream.c,v $
-- $Date: 2008/03/13 12:48:06 $
-- $Revision: 1.1 $
--
------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------
1. Include headers
------------------------------------------------------------------------------*/
#include "h264hwd_util.h"
#include "h264hwd_stream.h"
/*------------------------------------------------------------------------------
2. External compiler flags
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
3. Module defines
------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------
4. Local function prototypes
------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------
Function: h264bsdGetBits
Functional description:
Read and remove bits from the stream buffer.
Input:
pStrmData pointer to stream data structure
numBits number of bits to read
Output:
none
Returns:
bits read from stream
END_OF_STREAM if not enough bits left
------------------------------------------------------------------------------*/
u32 h264bsdGetBits(strmData_t * pStrmData, u32 numBits)
{
u32 out;
ASSERT(pStrmData);
ASSERT(numBits < 32);
out = h264bsdShowBits(pStrmData, 32) >> (32 - numBits);
if(h264bsdFlushBits(pStrmData, numBits) == HANTRO_OK)
{
return (out);
}
else
{
return (END_OF_STREAM);
}
}
/*------------------------------------------------------------------------------
5.2 Function: HwShowBits
Functional description:
Read bits from input stream. Bits are located right
aligned in the 32-bit output word. In case stream ends,
function fills the word with zeros. For example, numBits = 18 and
there are 7 bits left in the stream buffer -> return
00000000000000xxxxxxx00000000000,
where 'x's represent actual bits read from buffer.
Input:
Output:
------------------------------------------------------------------------------*/
u32 h264bsdShowBits(strmData_t * pStrmData, u32 numBits)
{
i32 bits;
u32 out, outBits;
u32 tmpReadBits;
const u8 *pStrm;
ASSERT(pStrmData);
ASSERT(pStrmData->pStrmCurrPos);
ASSERT(pStrmData->bitPosInWord < 8);
ASSERT(pStrmData->bitPosInWord == (pStrmData->strmBuffReadBits & 0x7));
ASSERT(numBits <= 32);
pStrm = pStrmData->pStrmCurrPos;
/* bits left in the buffer */
bits =
(i32) pStrmData->strmBuffSize * 8 - (i32) pStrmData->strmBuffReadBits;
if(/*!numBits || */!bits) /* for the moment is always called with numBits = 32 */
{
return (0);
}
if(!pStrmData->removeEmul3Byte)
{
out = outBits = 0;
tmpReadBits = pStrmData->strmBuffReadBits;
if(pStrmData->bitPosInWord)
{
out = pStrm[0] << (24 + pStrmData->bitPosInWord);
pStrm++;
outBits = 8 - pStrmData->bitPosInWord;
bits -= outBits;
tmpReadBits += outBits;
}
while(bits && outBits < numBits)
{
/* check emulation prevention byte */
if(tmpReadBits >= 16 &&
pStrm[-2] == 0x0 && pStrm[-1] == 0x0 && pStrm[0] == 0x3)
{
pStrm++;
tmpReadBits += 8;
bits -= 8;
/* emulation prevention byte shall not be the last byte of the
* stream */
if(bits <= 0)
break;
}
tmpReadBits += 8;
if(outBits <= 24)
out |= (u32) (*pStrm++) << (24 - outBits);
else
out |= (u32) (*pStrm++) >> (outBits - 24);
outBits += 8;
bits -= 8;
}
return (out >> (32 - numBits));
}
else
{
u32 shift;
/* at least 32-bits in the buffer */
if(bits >= 32)
{
u32 bitPosInWord = pStrmData->bitPosInWord;
out = ((u32) pStrm[3]) | ((u32) pStrm[2] << 8) |
((u32) pStrm[1] << 16) | ((u32) pStrm[0] << 24);
if(bitPosInWord)
{
out <<= bitPosInWord;
out |= (u32) pStrm[4] >> (8 - bitPosInWord);
}
return (out >> (32 - numBits));
}
/* at least one bit in the buffer */
else if(bits > 0)
{
shift = (i32) (24 + pStrmData->bitPosInWord);
out = (u32) (*pStrm++) << shift;
bits -= (i32) (8 - pStrmData->bitPosInWord);
while(bits > 0)
{
shift -= 8;
out |= (u32) (*pStrm++) << shift;
bits -= 8;
}
return (out >> (32 - numBits));
}
else
return (0);
}
}
/*------------------------------------------------------------------------------
Function: h264bsdFlushBits
Functional description:
Remove bits from the stream buffer
Input:
pStrmData pointer to stream data structure
numBits number of bits to remove
Output:
none
Returns:
HANTRO_OK success
END_OF_STREAM not enough bits left
------------------------------------------------------------------------------*/
u32 h264bsdFlushBits(strmData_t * pStrmData, u32 numBits)
{
u32 bytesLeft;
const u8 *pStrm;
ASSERT(pStrmData);
ASSERT(pStrmData->pStrmBuffStart);
ASSERT(pStrmData->pStrmCurrPos);
ASSERT(pStrmData->bitPosInWord < 8);
ASSERT(pStrmData->bitPosInWord == (pStrmData->strmBuffReadBits & 0x7));
if(!pStrmData->removeEmul3Byte)
{
if((pStrmData->strmBuffReadBits + numBits) >
(8 * pStrmData->strmBuffSize))
{
pStrmData->strmBuffReadBits = 8 * pStrmData->strmBuffSize;
pStrmData->bitPosInWord = 0;
pStrmData->pStrmCurrPos =
pStrmData->pStrmBuffStart + pStrmData->strmBuffSize;
return (END_OF_STREAM);
}
else
{
bytesLeft =
(8 * pStrmData->strmBuffSize - pStrmData->strmBuffReadBits) / 8;
pStrm = pStrmData->pStrmCurrPos;
if(pStrmData->bitPosInWord)
{
if(numBits < 8 - pStrmData->bitPosInWord)
{
pStrmData->strmBuffReadBits += numBits;
pStrmData->bitPosInWord += numBits;
return (HANTRO_OK);
}
numBits -= 8 - pStrmData->bitPosInWord;
pStrmData->strmBuffReadBits += 8 - pStrmData->bitPosInWord;
pStrmData->bitPosInWord = 0;
pStrm++;
if(pStrmData->strmBuffReadBits >= 16 && bytesLeft &&
pStrm[-2] == 0x0 && pStrm[-1] == 0x0 && pStrm[0] == 0x3)
{
pStrm++;
pStrmData->strmBuffReadBits += 8;
bytesLeft--;
pStrmData->emulByteCount++;
}
}
while(numBits >= 8 && bytesLeft)
{
if(bytesLeft > 2 && pStrm[0] == 0 && pStrm[1] == 0 &&
pStrm[2] <= 1)
{
/* trying to flush part of start code prefix -> error */
return (HANTRO_NOK);
}
pStrm++;
pStrmData->strmBuffReadBits += 8;
bytesLeft--;
/* check emulation prevention byte */
if(pStrmData->strmBuffReadBits >= 16 && bytesLeft &&
pStrm[-2] == 0x0 && pStrm[-1] == 0x0 && pStrm[0] == 0x3)
{
pStrm++;
pStrmData->strmBuffReadBits += 8;
bytesLeft--;
pStrmData->emulByteCount++;
}
numBits -= 8;
}
if(numBits && bytesLeft)
{
if(bytesLeft > 2 && pStrm[0] == 0 && pStrm[1] == 0 &&
pStrm[2] <= 1)
{
/* trying to flush part of start code prefix -> error */
return (HANTRO_NOK);
}
pStrmData->strmBuffReadBits += numBits;
pStrmData->bitPosInWord = numBits;
numBits = 0;
}
pStrmData->pStrmCurrPos = pStrm;
if(numBits)
return (END_OF_STREAM);
else
return (HANTRO_OK);
}
}
else
{
pStrmData->strmBuffReadBits += numBits;
pStrmData->bitPosInWord = pStrmData->strmBuffReadBits & 0x7;
if((pStrmData->strmBuffReadBits) <= (8 * pStrmData->strmBuffSize))
{
pStrmData->pStrmCurrPos = pStrmData->pStrmBuffStart +
(pStrmData->strmBuffReadBits >> 3);
return (HANTRO_OK);
}
else
return (END_OF_STREAM);
}
}
/*------------------------------------------------------------------------------
Function: h264bsdIsByteAligned
Functional description:
Check if current stream position is byte aligned.
Inputs:
pStrmData pointer to stream data structure
Outputs:
none
Returns:
HANTRO_TRUE stream is byte aligned
HANTRO_FALSE stream is not byte aligned
------------------------------------------------------------------------------*/
u32 h264bsdIsByteAligned(strmData_t * pStrmData)
{
/* Variables */
/* Code */
if(!pStrmData->bitPosInWord)
return (HANTRO_TRUE);
else
return (HANTRO_FALSE);
}

View File

@ -0,0 +1,388 @@
/*------------------------------------------------------------------------------
-- --
-- This software is confidential and proprietary and may be used --
-- only as expressly authorized by a licensing agreement from --
-- --
-- Hantro Products Oy. --
-- --
-- (C) COPYRIGHT 2006 HANTRO PRODUCTS OY --
-- ALL RIGHTS RESERVED --
-- --
-- The entire notice above must be reproduced --
-- on all copies and should not be removed. --
-- --
--------------------------------------------------------------------------------
--
-- Abstract : Utility macros and functions
--
--------------------------------------------------------------------------------
--
-- Version control information, please leave untouched.
--
-- $RCSfile: h264hwd_util.c,v $
-- $Date: 2008/10/01 12:30:48 $
-- $Revision: 1.3 $
--
------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------
Table of contents
1. Include headers
2. External compiler flags
3. Module defines
4. Local function prototypes
5. Functions
h264bsdCountLeadingZeros
h264bsdRbspTrailingBits
h264bsdMoreRbspData
h264bsdNextMbAddress
------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------
1. Include headers
------------------------------------------------------------------------------*/
#include "h264hwd_util.h"
/*------------------------------------------------------------------------------
2. External compiler flags
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
3. Module defines
------------------------------------------------------------------------------*/
/* look-up table for expected values of stuffing bits */
//static const u32 stuffingTable[8] = {0x1,0x2,0x4,0x8,0x10,0x20,0x40,0x80};
/* look-up table for chroma quantization parameter as a function of luma QP */
const u32 h264bsdQpC[52] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,
20,21,22,23,24,25,26,27,28,29,29,30,31,32,32,33,34,34,35,35,36,36,37,37,37,
38,38,38,39,39,39,39};
/*------------------------------------------------------------------------------
4. Local function prototypes
------------------------------------------------------------------------------*/
static u32 MoreRbspTrailingData(strmData_t *pStrmData);
/*------------------------------------------------------------------------------
5.1 Function: h264bsdCountLeadingZeros
Functional description:
Count leading zeros in a code word. Code word is assumed to be
right-aligned, last bit of the code word in the lsb of the value.
Inputs:
value code word
length number of bits in the code word
Outputs:
none
Returns:
number of leading zeros in the code word
------------------------------------------------------------------------------*/
u32 h264bsdCountLeadingZeros(u32 value, u32 length)
{
/* Variables */
u32 zeros = 0;
u32 mask = 1 << (length - 1);
/* Code */
ASSERT(length <= 32);
while (mask && !(value & mask))
{
zeros++;
mask >>= 1;
}
return(zeros);
}
/*------------------------------------------------------------------------------
5.2 Function: h264bsdRbspTrailingBits
Functional description:
Check Raw Byte Stream Payload (RBSP) trailing bits, i.e. stuffing.
Rest of the current byte (whole byte if allready byte aligned)
in the stream buffer shall contain a '1' bit followed by zero or
more '0' bits.
Inputs:
pStrmData pointer to stream data structure
Outputs:
none
Returns:
HANTRO_OK RBSP trailing bits found
HANTRO_NOK otherwise
------------------------------------------------------------------------------*/
u32 h264bsdRbspTrailingBits(strmData_t *pStrmData)
{
/* Variables */
u32 stuffing;
u32 stuffingLength;
/* Code */
ASSERT(pStrmData);
ASSERT(pStrmData->bitPosInWord < 8);
stuffingLength = 8 - pStrmData->bitPosInWord;
stuffing = h264bsdGetBits(pStrmData, stuffingLength);
if (stuffing == END_OF_STREAM)
return(HANTRO_NOK);
#ifdef HANTRO_PEDANTIC_MODE
if (stuffing != stuffingTable[stuffingLength - 1])
return(HANTRO_NOK);
else
#endif
return(HANTRO_OK);
}
/*------------------------------------------------------------------------------
5.2 Function: h264bsdRbspSliceTrailingBits
Functional description:
Check slice trailing bits if CABAC is on.
Inputs:
pStrmData pointer to stream data structure
Outputs:
none
Returns:
HANTRO_OK RBSP slice trailing bits found
HANTRO_NOK otherwise
------------------------------------------------------------------------------*/
#ifdef H264_CABAC
u32 h264bsdRbspSliceTrailingBits(strmData_t *pStrmData)
{
/* Variables */
u32 czw;
u32 tmp;
/* Code */
ASSERT(pStrmData);
ASSERT(pStrmData->bitPosInWord < 8);
if( pStrmData->bitPosInWord > 0 )
h264bsdRbspTrailingBits( pStrmData );
while(MoreRbspTrailingData( pStrmData ))
{
/* Read 16 bits */
czw = h264bsdShowBits(pStrmData, 16 );
tmp = h264bsdFlushBits(pStrmData, 16);
if (tmp == END_OF_STREAM || czw)
return(END_OF_STREAM);
}
return (HANTRO_OK);
}
#endif /* H264_CABAC */
/*------------------------------------------------------------------------------
5.6 Function: MoreRbspTrailingData
Functional description:
<++>
Inputs:
<++>
Outputs:
<++>
------------------------------------------------------------------------------*/
u32 MoreRbspTrailingData(strmData_t *pStrmData)
{
/* Variables */
i32 bits;
/* Code */
ASSERT(pStrmData);
ASSERT(pStrmData->strmBuffReadBits <= 8 * pStrmData->strmBuffSize);
bits = (i32)pStrmData->strmBuffSize*8 - (i32)pStrmData->strmBuffReadBits;
if ( bits >= 8 )
return(HANTRO_TRUE);
else
return(HANTRO_FALSE);
}
/*------------------------------------------------------------------------------
5.3 Function: h264bsdMoreRbspData
Functional description:
Check if there is more data in the current RBSP. The standard
defines this function so that there is more data if
-more than 8 bits left or
-last bits are not RBSP trailing bits
Inputs:
pStrmData pointer to stream data structure
Outputs:
none
Returns:
HANTRO_TRUE there is more data
HANTRO_FALSE no more data
------------------------------------------------------------------------------*/
u32 h264bsdMoreRbspData(strmData_t *pStrmData)
{
/* Variables */
u32 bits;
/* Code */
ASSERT(pStrmData);
ASSERT(pStrmData->strmBuffReadBits <= 8 * pStrmData->strmBuffSize);
bits = pStrmData->strmBuffSize * 8 - pStrmData->strmBuffReadBits;
if (bits == 0)
return(HANTRO_FALSE);
if (bits > 8)
{
if (pStrmData->removeEmul3Byte)
return(HANTRO_TRUE);
bits &= 0x7;
if (!bits) bits = 8;
if (h264bsdShowBits(pStrmData, bits) != (1 << (bits-1)) ||
(h264bsdShowBits(pStrmData, 23+bits) << 9))
return(HANTRO_TRUE);
else
return(HANTRO_FALSE);
}
else if (h264bsdShowBits(pStrmData,bits) != (1 << (bits-1)) )
return(HANTRO_TRUE);
else
return(HANTRO_FALSE);
}
/*------------------------------------------------------------------------------
5.4 Function: h264bsdNextMbAddress
Functional description:
Get address of the next macroblock in the current slice group.
Inputs:
pSliceGroupMap slice group for each macroblock
picSizeInMbs size of the picture
currMbAddr where to start
Outputs:
none
Returns:
address of the next macroblock
0 if none of the following macroblocks belong to same slice
group as currMbAddr
------------------------------------------------------------------------------*/
u32 h264bsdNextMbAddress(u32 *pSliceGroupMap, u32 picSizeInMbs, u32 currMbAddr)
{
/* Variables */
u32 i, sliceGroup;
/* Code */
ASSERT(pSliceGroupMap);
ASSERT(picSizeInMbs);
ASSERT(currMbAddr < picSizeInMbs);
sliceGroup = pSliceGroupMap[currMbAddr];
i = currMbAddr + 1;
while ((i < picSizeInMbs) && (pSliceGroupMap[i] != sliceGroup))
i++;
if (i == picSizeInMbs)
i = 0;
return(i);
}
/*------------------------------------------------------------------------------
5.4 Function: h264CheckCabacZeroWords
Functional description:
Inputs:
Outputs:
Returns:
------------------------------------------------------------------------------*/
u32 h264CheckCabacZeroWords( strmData_t *strmData )
{
/* Variables */
u32 tmp;
/* Code */
ASSERT(strmData);
while (MoreRbspTrailingData(strmData))
{
tmp = h264bsdGetBits(strmData, 16 );
if( tmp == END_OF_STREAM )
return HANTRO_OK;
else if ( tmp )
return HANTRO_NOK;
}
return HANTRO_OK;
}

View File

@ -0,0 +1,402 @@
/*------------------------------------------------------------------------------
-- --
-- This software is confidential and proprietary and may be used --
-- only as expressly authorized by a licensing agreement from --
-- --
-- Hantro Products Oy. --
-- --
-- (C) COPYRIGHT 2006 HANTRO PRODUCTS OY --
-- ALL RIGHTS RESERVED --
-- --
-- The entire notice above must be reproduced --
-- on all copies and should not be removed. --
-- --
--------------------------------------------------------------------------------
--
-- Abstract : Decode Exp-Golomb code words
--
--------------------------------------------------------------------------------
--
-- Version control information, please leave untouched.
--
-- $RCSfile: h264hwd_vlc.c,v $
-- $Date: 2008/03/13 12:48:06 $
-- $Revision: 1.1 $
--
------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------
Table of contents
1. Include headers
2. External compiler flags
3. Module defines
4. Local function prototypes
5. Functions
h264bsdDecodeExpGolombUnsigned
h264bsdDecodeExpGolombSigned
h264bsdDecodeExpGolombMapped
h264bsdDecodeExpGolombTruncated
------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------
1. Include headers
------------------------------------------------------------------------------*/
#include "h264hwd_vlc.h"
#include "basetype.h"
#include "h264hwd_stream.h"
#include "h264hwd_util.h"
/*------------------------------------------------------------------------------
2. External compiler flags
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
3. Module defines
------------------------------------------------------------------------------*/
/* definition of special code num, this along with the return value is used
* to handle code num in the range [0, 2^32] in the DecodeExpGolombUnsigned
* function */
#define BIG_CODE_NUM 0xFFFFFFFFU
/* Mapping tables for coded_block_pattern, used for decoding of mapped
* Exp-Golomb codes */
static const u8 codedBlockPatternIntra4x4[48] = {
47,31,15,0,23,27,29,30,7,11,13,14,39,43,45,46,16,3,5,10,12,19,21,26,28,35,
37,42,44,1,2,4,8,17,18,20,24,6,9,22,25,32,33,34,36,40,38,41};
static const u8 codedBlockPatternInter[48] = {
0,16,1,2,4,8,32,3,5,10,12,15,47,7,11,13,14,6,9,31,35,37,42,44,33,34,36,40,
39,43,45,46,17,18,20,24,19,21,26,28,23,27,29,30,22,25,38,41};
/*------------------------------------------------------------------------------
4. Local function prototypes
------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------
5.1 Function: h264bsdDecodeExpGolombUnsigned
Functional description:
Decode unsigned Exp-Golomb code. This is the same as codeNum used
in other Exp-Golomb code mappings. Code num (i.e. the decoded
symbol) is determined as
codeNum = 2^leadingZeros - 1 + GetBits(leadingZeros)
Normal decoded symbols are in the range [0, 2^32 - 2]. Symbol
2^32-1 is indicated by BIG_CODE_NUM with return value HANTRO_OK
while symbol 2^32 is indicated by BIG_CODE_NUM with return value
HANTRO_NOK. These two symbols are special cases with code length
of 65, i.e. 32 '0' bits, a '1' bit, and either 0 or 1 represented
by 32 bits.
Symbol 2^32 is out of unsigned 32-bit range but is needed for
DecodeExpGolombSigned to express value -2^31.
Inputs:
pStrmData pointer to stream data structure
Outputs:
codeNum decoded code word is stored here
Returns:
HANTRO_OK success
HANTRO_NOK failure, no valid code word found, note exception
with BIG_CODE_NUM
------------------------------------------------------------------------------*/
u32 h264bsdDecodeExpGolombUnsigned(strmData_t *pStrmData, u32 *codeNum)
{
/* Variables */
u32 bits, numZeros;
/* Code */
ASSERT(pStrmData);
ASSERT(codeNum);
bits = h264bsdShowBits(pStrmData,32);
/* first bit is 1 -> code length 1 */
if (bits >= 0x80000000)
{
if (h264bsdFlushBits(pStrmData, 1)== END_OF_STREAM)
return(HANTRO_NOK);
*codeNum = 0;
return(HANTRO_OK);
}
/* second bit is 1 -> code length 3 */
else if (bits >= 0x40000000)
{
if (h264bsdFlushBits(pStrmData, 3) == END_OF_STREAM)
return(HANTRO_NOK);
*codeNum = 1 + ((bits >> 29) & 0x1);
return(HANTRO_OK);
}
/* third bit is 1 -> code length 5 */
else if (bits >= 0x20000000)
{
if (h264bsdFlushBits(pStrmData, 5) == END_OF_STREAM)
return(HANTRO_NOK);
*codeNum = 3 + ((bits >> 27) & 0x3);
return(HANTRO_OK);
}
/* fourth bit is 1 -> code length 7 */
else if (bits >= 0x10000000)
{
if (h264bsdFlushBits(pStrmData, 7) == END_OF_STREAM)
return(HANTRO_NOK);
*codeNum = 7 + ((bits >> 25) & 0x7);
return(HANTRO_OK);
}
/* other code lengths */
else
{
numZeros = 4 + h264bsdCountLeadingZeros(bits, 28);
/* all 32 bits are zero */
if (numZeros == 32)
{
*codeNum = 0;
if (h264bsdFlushBits(pStrmData,32) == END_OF_STREAM)
return(HANTRO_NOK);
bits = h264bsdGetBits(pStrmData, 1);
/* check 33rd bit, must be 1 */
if (bits == 1)
{
/* cannot use h264bsdGetBits, limited to 31 bits */
bits = h264bsdShowBits(pStrmData,32);
if (h264bsdFlushBits(pStrmData, 32) == END_OF_STREAM)
return(HANTRO_NOK);
/* code num 2^32 - 1, needed for unsigned mapping */
if (bits == 0)
{
*codeNum = BIG_CODE_NUM;
return(HANTRO_OK);
}
/* code num 2^32, needed for unsigned mapping
* (results in -2^31) */
else if (bits == 1)
{
*codeNum = BIG_CODE_NUM;
return(HANTRO_NOK);
}
}
/* if more zeros than 32, it is an error */
return(HANTRO_NOK);
}
else
if (h264bsdFlushBits(pStrmData,numZeros+1) == END_OF_STREAM)
return(HANTRO_NOK);
bits = h264bsdGetBits(pStrmData, numZeros);
if (bits == END_OF_STREAM)
return(HANTRO_NOK);
*codeNum = (1 << numZeros) - 1 + bits;
}
return(HANTRO_OK);
}
/*------------------------------------------------------------------------------
5.2 Function: h264bsdDecodeExpGolombSigned
Functional description:
Decode signed Exp-Golomb code. Code num is determined by
h264bsdDecodeExpGolombUnsigned and then mapped to signed
representation as
symbol = (-1)^(codeNum+1) * (codeNum+1)/2
Signed symbols shall be in the range [-2^31, 2^31 - 1]. Symbol
-2^31 is obtained when codeNum is 2^32, which cannot be expressed
by unsigned 32-bit value. This is signaled as a special case from
the h264bsdDecodeExpGolombUnsigned by setting codeNum to
BIG_CODE_NUM and returning HANTRO_NOK status.
Inputs:
pStrmData pointer to stream data structure
Outputs:
value decoded code word is stored here
Returns:
HANTRO_OK success
HANTRO_NOK failure, no valid code word found
------------------------------------------------------------------------------*/
u32 h264bsdDecodeExpGolombSigned(strmData_t *pStrmData, i32 *value)
{
/* Variables */
u32 status, codeNum = 0;
/* Code */
ASSERT(pStrmData);
ASSERT(value);
status = h264bsdDecodeExpGolombUnsigned(pStrmData, &codeNum);
if (codeNum == BIG_CODE_NUM)
{
/* BIG_CODE_NUM and HANTRO_OK status means codeNum 2^32-1 which would
* result in signed integer valued 2^31 (i.e. out of 32-bit signed
* integer range) */
if (status == HANTRO_OK)
return(HANTRO_NOK);
/* BIG_CODE_NUM and HANTRO_NOK status means codeNum 2^32 which results
* in signed integer valued -2^31 */
else
{
*value = (i32)(2147483648U);
return (HANTRO_OK);
}
}
else if (status == HANTRO_OK)
{
/* (-1)^(codeNum+1) results in positive sign if codeNum is odd,
* negative when it is even. (codeNum+1)/2 is obtained as
* (codeNum+1)>>1 when value is positive and as (-codeNum)>>1 for
* negative value */
/*lint -e702 */
*value = (codeNum & 0x1) ? (i32)((codeNum + 1) >> 1) :
-(i32)((codeNum + 1) >> 1);
/*lint +e702 */
return(HANTRO_OK);
}
return(HANTRO_NOK);
}
/*------------------------------------------------------------------------------
5.3 Function: h264bsdDecodeExpGolombMapped
Functional description:
Decode mapped Exp-Golomb code. Code num is determined by
h264bsdDecodeExpGolombUnsigned and then mapped to codedBlockPattern
either for intra or inter macroblock. The mapping is implemented by
look-up tables defined in the beginning of the file.
Inputs:
pStrmData pointer to stream data structure
isIntra flag to indicate if intra or inter mapping is to
be used
Outputs:
value decoded code word is stored here
Returns:
HANTRO_OK success
HANTRO_NOK failure, no valid code word found
------------------------------------------------------------------------------*/
u32 h264bsdDecodeExpGolombMapped(strmData_t *pStrmData, u32 *value,
u32 isIntra)
{
/* Variables */
u32 status, codeNum;
/* Code */
ASSERT(pStrmData);
ASSERT(value);
status = h264bsdDecodeExpGolombUnsigned(pStrmData, &codeNum);
if (status != HANTRO_OK)
return (HANTRO_NOK);
else
{
/* range of valid codeNums [0,47] */
if (codeNum > 47)
return (HANTRO_NOK);
if (isIntra)
*value = codedBlockPatternIntra4x4[codeNum];
else
*value = codedBlockPatternInter[codeNum];
return(HANTRO_OK);
}
}
/*------------------------------------------------------------------------------
5.4 Function: h264bsdDecodeExpGolombTruncated
Functional description:
Decode truncated Exp-Golomb code. greaterThanOne flag indicates
the range of the symbol to be decoded as follows:
HANTRO_FALSE -> [0,1]
HANTRO_TRUE -> [0,2^32-1]
If flag is false the decoding is performed by reading one bit
from the stream with h264bsdGetBits and mapping this to decoded
symbol as
symbol = bit ? 0 : 1
Otherwise, i.e. when flag is HANTRO_TRUE, code num is determined by
h264bsdDecodeExpGolombUnsigned and this is used as the decoded
symbol.
Inputs:
pStrmData pointer to stream data structure
greaterThanOne flag to indicate if range is wider than [0,1]
Outputs:
value decoded code word is stored here
Returns:
HANTRO_OK success
HANTRO_NOK failure, no valid code word found
------------------------------------------------------------------------------*/
u32 h264bsdDecodeExpGolombTruncated(
strmData_t *pStrmData,
u32 *value,
u32 greaterThanOne)
{
/* Variables */
/* Code */
ASSERT(pStrmData);
ASSERT(value);
if (greaterThanOne)
{
return(h264bsdDecodeExpGolombUnsigned(pStrmData, value));
}
else
{
*value = h264bsdGetBits(pStrmData,1);
if (*value == END_OF_STREAM)
return (HANTRO_NOK);
*value ^= 0x1;
}
return (HANTRO_OK);
}

View File

@ -0,0 +1,506 @@
/*------------------------------------------------------------------------------
-- --
-- This software is confidential and proprietary and may be used --
-- only as expressly authorized by a licensing agreement from --
-- --
-- Hantro Products Oy. --
-- --
-- (C) COPYRIGHT 2006 HANTRO PRODUCTS OY --
-- ALL RIGHTS RESERVED --
-- --
-- The entire notice above must be reproduced --
-- on all copies and should not be removed. --
-- --
--------------------------------------------------------------------------------
--
-- Abstract : Decode Video Usability Information (VUI) from the stream
--
--------------------------------------------------------------------------------
--
-- Version control information, please leave untouched.
--
-- $RCSfile: h264hwd_vui.c,v $
-- $Date: 2009/05/15 08:42:26 $
-- $Revision: 1.3 $
--
------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------
Table of contents
1. Include headers
2. External compiler flags
3. Module defines
4. Local function prototypes
5. Functions
h264bsdDecodeVuiParameters
DecodeHrdParameters
------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------
1. Include headers
------------------------------------------------------------------------------*/
#include "dwl.h"
#include "h264hwd_vui.h"
#include "basetype.h"
#include "h264hwd_vlc.h"
#include "h264hwd_stream.h"
#include "h264hwd_util.h"
/*------------------------------------------------------------------------------
2. External compiler flags
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
3. Module defines
------------------------------------------------------------------------------*/
#define MAX_DPB_SIZE 16
#define MAX_BR 240000 /* for level 5.1 */
#define MAX_CPB 240000 /* for level 5.1 */
/*------------------------------------------------------------------------------
4. Local function prototypes
------------------------------------------------------------------------------*/
static u32 DecodeHrdParameters(
strmData_t *pStrmData,
hrdParameters_t *pHrdParameters);
/*------------------------------------------------------------------------------
Function: h264bsdDecodeVuiParameters
Functional description:
Decode VUI parameters from the stream. See standard for details.
Inputs:
pStrmData pointer to stream data structure
Outputs:
pVuiParameters decoded information is stored here
Returns:
HANTRO_OK success
HANTRO_NOK invalid stream data or end of stream
------------------------------------------------------------------------------*/
u32 h264bsdDecodeVuiParameters(strmData_t *pStrmData,
vuiParameters_t *pVuiParameters)
{
/* Variables */
u32 tmp;
/* Code */
ASSERT(pStrmData);
ASSERT(pVuiParameters);
(void) DWLmemset(pVuiParameters, 0, sizeof(vuiParameters_t));
tmp = h264bsdGetBits(pStrmData, 1);
if (tmp == END_OF_STREAM)
return(END_OF_STREAM);
pVuiParameters->aspectRatioPresentFlag = (tmp == 1) ? HANTRO_TRUE : HANTRO_FALSE;
if (pVuiParameters->aspectRatioPresentFlag)
{
tmp = h264bsdGetBits(pStrmData, 8);
if (tmp == END_OF_STREAM)
return(END_OF_STREAM);
pVuiParameters->aspectRatioIdc = tmp;
if (pVuiParameters->aspectRatioIdc == ASPECT_RATIO_EXTENDED_SAR)
{
tmp = h264bsdGetBits(pStrmData, 16);
if (tmp == END_OF_STREAM)
return(END_OF_STREAM);
pVuiParameters->sarWidth = tmp;
tmp = h264bsdGetBits(pStrmData, 16);
if (tmp == END_OF_STREAM)
return(END_OF_STREAM);
pVuiParameters->sarHeight = tmp;
}
}
tmp = h264bsdGetBits(pStrmData, 1);
if (tmp == END_OF_STREAM)
return(END_OF_STREAM);
pVuiParameters->overscanInfoPresentFlag = (tmp == 1) ? HANTRO_TRUE : HANTRO_FALSE;
if (pVuiParameters->overscanInfoPresentFlag)
{
tmp = h264bsdGetBits(pStrmData, 1);
if (tmp == END_OF_STREAM)
return(END_OF_STREAM);
pVuiParameters->overscanAppropriateFlag = (tmp == 1) ? HANTRO_TRUE : HANTRO_FALSE;
}
tmp = h264bsdGetBits(pStrmData, 1);
if (tmp == END_OF_STREAM)
return(END_OF_STREAM);
pVuiParameters->videoSignalTypePresentFlag = (tmp == 1) ? HANTRO_TRUE : HANTRO_FALSE;
if (pVuiParameters->videoSignalTypePresentFlag)
{
tmp = h264bsdGetBits(pStrmData, 3);
if (tmp == END_OF_STREAM)
return(END_OF_STREAM);
pVuiParameters->videoFormat = tmp;
tmp = h264bsdGetBits(pStrmData, 1);
if (tmp == END_OF_STREAM)
return(END_OF_STREAM);
pVuiParameters->videoFullRangeFlag = (tmp == 1) ? HANTRO_TRUE : HANTRO_FALSE;
tmp = h264bsdGetBits(pStrmData, 1);
if (tmp == END_OF_STREAM)
return(END_OF_STREAM);
pVuiParameters->colourDescriptionPresentFlag =
(tmp == 1) ? HANTRO_TRUE : HANTRO_FALSE;
if (pVuiParameters->colourDescriptionPresentFlag)
{
tmp = h264bsdGetBits(pStrmData, 8);
if (tmp == END_OF_STREAM)
return(END_OF_STREAM);
pVuiParameters->colourPrimaries = tmp;
tmp = h264bsdGetBits(pStrmData, 8);
if (tmp == END_OF_STREAM)
return(END_OF_STREAM);
pVuiParameters->transferCharacteristics = tmp;
tmp = h264bsdGetBits(pStrmData, 8);
if (tmp == END_OF_STREAM)
return(END_OF_STREAM);
pVuiParameters->matrixCoefficients = tmp;
}
else
{
pVuiParameters->colourPrimaries = 2;
pVuiParameters->transferCharacteristics = 2;
pVuiParameters->matrixCoefficients = 2;
}
}
else
{
pVuiParameters->videoFormat = 5;
pVuiParameters->colourPrimaries = 2;
pVuiParameters->transferCharacteristics = 2;
pVuiParameters->matrixCoefficients = 2;
}
tmp = h264bsdGetBits(pStrmData, 1);
if (tmp == END_OF_STREAM)
return(END_OF_STREAM);
pVuiParameters->chromaLocInfoPresentFlag = (tmp == 1) ? HANTRO_TRUE : HANTRO_FALSE;
if (pVuiParameters->chromaLocInfoPresentFlag)
{
tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
&pVuiParameters->chromaSampleLocTypeTopField);
if (tmp != HANTRO_OK)
return(tmp);
if (pVuiParameters->chromaSampleLocTypeTopField > 5)
return(END_OF_STREAM);
tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
&pVuiParameters->chromaSampleLocTypeBottomField);
if (tmp != HANTRO_OK)
return(tmp);
if (pVuiParameters->chromaSampleLocTypeBottomField > 5)
return(END_OF_STREAM);
}
tmp = h264bsdGetBits(pStrmData, 1);
if (tmp == END_OF_STREAM)
return(END_OF_STREAM);
pVuiParameters->timingInfoPresentFlag = (tmp == 1) ? HANTRO_TRUE : HANTRO_FALSE;
if (pVuiParameters->timingInfoPresentFlag)
{
tmp = h264bsdShowBits(pStrmData,32);
if (h264bsdFlushBits(pStrmData, 32) == END_OF_STREAM)
return(END_OF_STREAM);
#ifdef HANTRO_PEDANTIC_MODE
if (tmp == 0)
return(HANTRO_NOK);
#endif /* HANTRO_PEDANTIC_MODE */
pVuiParameters->numUnitsInTick = tmp;
tmp = h264bsdShowBits(pStrmData,32);
if (h264bsdFlushBits(pStrmData, 32) == END_OF_STREAM)
return(END_OF_STREAM);
#ifdef HANTRO_PEDANTIC_MODE
if (tmp == 0)
return(HANTRO_NOK);
#endif /* HANTRO_PEDANTIC_MODE */
pVuiParameters->timeScale = tmp;
tmp = h264bsdGetBits(pStrmData, 1);
if (tmp == END_OF_STREAM)
return(END_OF_STREAM);
pVuiParameters->fixedFrameRateFlag = (tmp == 1) ? HANTRO_TRUE : HANTRO_FALSE;
}
tmp = h264bsdGetBits(pStrmData, 1);
if (tmp == END_OF_STREAM)
return(END_OF_STREAM);
pVuiParameters->nalHrdParametersPresentFlag = (tmp == 1) ? HANTRO_TRUE : HANTRO_FALSE;
if (pVuiParameters->nalHrdParametersPresentFlag)
{
tmp = DecodeHrdParameters(pStrmData, &pVuiParameters->nalHrdParameters);
if (tmp != HANTRO_OK)
{
/* ignore error */
return(HANTRO_OK);
}
}
else
{
pVuiParameters->nalHrdParameters.cpbCnt = 1;
/* MaxBR and MaxCPB should be the values correspondig to the levelIdc
* in the SPS containing these VUI parameters. However, these values
* are not used anywhere and maximum for any level will be used here */
pVuiParameters->nalHrdParameters.bitRateValue[0] = 1200 * MAX_BR + 1;
pVuiParameters->nalHrdParameters.cpbSizeValue[0] = 1200 * MAX_CPB + 1;
pVuiParameters->nalHrdParameters.initialCpbRemovalDelayLength = 24;
pVuiParameters->nalHrdParameters.cpbRemovalDelayLength = 24;
pVuiParameters->nalHrdParameters.dpbOutputDelayLength = 24;
pVuiParameters->nalHrdParameters.timeOffsetLength = 24;
}
tmp = h264bsdGetBits(pStrmData, 1);
if (tmp == END_OF_STREAM)
return(END_OF_STREAM);
pVuiParameters->vclHrdParametersPresentFlag = (tmp == 1) ? HANTRO_TRUE : HANTRO_FALSE;
if (pVuiParameters->vclHrdParametersPresentFlag)
{
tmp = DecodeHrdParameters(pStrmData, &pVuiParameters->vclHrdParameters);
if (tmp != HANTRO_OK)
{
/* ignore error */
return(HANTRO_OK);
}
}
else
{
pVuiParameters->vclHrdParameters.cpbCnt = 1;
/* MaxBR and MaxCPB should be the values correspondig to the levelIdc
* in the SPS containing these VUI parameters. However, these values
* are not used anywhere and maximum for any level will be used here */
pVuiParameters->vclHrdParameters.bitRateValue[0] = 1000 * MAX_BR + 1;
pVuiParameters->vclHrdParameters.cpbSizeValue[0] = 1000 * MAX_CPB + 1;
pVuiParameters->vclHrdParameters.initialCpbRemovalDelayLength = 24;
pVuiParameters->vclHrdParameters.cpbRemovalDelayLength = 24;
pVuiParameters->vclHrdParameters.dpbOutputDelayLength = 24;
pVuiParameters->vclHrdParameters.timeOffsetLength = 24;
}
if (pVuiParameters->nalHrdParametersPresentFlag ||
pVuiParameters->vclHrdParametersPresentFlag)
{
tmp = h264bsdGetBits(pStrmData, 1);
if (tmp == END_OF_STREAM)
return(END_OF_STREAM);
pVuiParameters->lowDelayHrdFlag = (tmp == 1) ? HANTRO_TRUE : HANTRO_FALSE;
}
tmp = h264bsdGetBits(pStrmData, 1);
if (tmp == END_OF_STREAM)
return(END_OF_STREAM);
pVuiParameters->picStructPresentFlag = (tmp == 1) ? HANTRO_TRUE : HANTRO_FALSE;
tmp = h264bsdGetBits(pStrmData, 1);
if (tmp == END_OF_STREAM)
return(END_OF_STREAM);
pVuiParameters->bitstreamRestrictionFlag = (tmp == 1) ? HANTRO_TRUE : HANTRO_FALSE;
if (pVuiParameters->bitstreamRestrictionFlag)
{
tmp = h264bsdGetBits(pStrmData, 1);
if (tmp == END_OF_STREAM)
return(END_OF_STREAM);
pVuiParameters->motionVectorsOverPicBoundariesFlag =
(tmp == 1) ? HANTRO_TRUE : HANTRO_FALSE;
tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
&pVuiParameters->maxBytesPerPicDenom);
if (tmp != HANTRO_OK)
return(tmp);
#ifdef HANTRO_PEDANTIC_MODE
if (pVuiParameters->maxBytesPerPicDenom > 16)
return(HANTRO_NOK);
#endif /* HANTRO_PEDANTIC_MODE */
tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
&pVuiParameters->maxBitsPerMbDenom);
if (tmp != HANTRO_OK)
return(tmp);
#ifdef HANTRO_PEDANTIC_MODE
if (pVuiParameters->maxBitsPerMbDenom > 16)
return(HANTRO_NOK);
#endif /* HANTRO_PEDANTIC_MODE */
tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
&pVuiParameters->log2MaxMvLengthHorizontal);
if (tmp != HANTRO_OK)
return(tmp);
#ifdef HANTRO_PEDANTIC_MODE
if (pVuiParameters->log2MaxMvLengthHorizontal > 16)
return(HANTRO_NOK);
#endif /* HANTRO_PEDANTIC_MODE */
tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
&pVuiParameters->log2MaxMvLengthVertical);
if (tmp != HANTRO_OK)
return(tmp);
#ifdef HANTRO_PEDANTIC_MODE
if (pVuiParameters->log2MaxMvLengthVertical > 16)
return(HANTRO_NOK);
#endif /* HANTRO_PEDANTIC_MODE */
tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
&pVuiParameters->numReorderFrames);
if (tmp != HANTRO_OK)
return(tmp);
tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
&pVuiParameters->maxDecFrameBuffering);
if (tmp != HANTRO_OK)
return(tmp);
}
else
{
pVuiParameters->motionVectorsOverPicBoundariesFlag = HANTRO_TRUE;
pVuiParameters->maxBytesPerPicDenom = 2;
pVuiParameters->maxBitsPerMbDenom = 1;
pVuiParameters->log2MaxMvLengthHorizontal = 16;
pVuiParameters->log2MaxMvLengthVertical = 16;
pVuiParameters->numReorderFrames = MAX_DPB_SIZE;
pVuiParameters->maxDecFrameBuffering = MAX_DPB_SIZE;
}
return(HANTRO_OK);
}
/*------------------------------------------------------------------------------
Function: DecodeHrdParameters
Functional description:
Decode HRD parameters from the stream. See standard for details.
Inputs:
pStrmData pointer to stream data structure
Outputs:
pHrdParameters decoded information is stored here
Returns:
HANTRO_OK success
HANTRO_NOK invalid stream data
------------------------------------------------------------------------------*/
static u32 DecodeHrdParameters(
strmData_t *pStrmData,
hrdParameters_t *pHrdParameters)
{
/* Variables */
u32 tmp, i;
/* Code */
ASSERT(pStrmData);
ASSERT(pHrdParameters);
tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &pHrdParameters->cpbCnt);
if (tmp != HANTRO_OK)
return(tmp);
/* cpbCount = cpb_cnt_minus1 + 1 */
pHrdParameters->cpbCnt++;
if (pHrdParameters->cpbCnt > MAX_CPB_CNT)
return(HANTRO_NOK);
tmp = h264bsdGetBits(pStrmData, 4);
if (tmp == END_OF_STREAM)
return(END_OF_STREAM);
pHrdParameters->bitRateScale = tmp;
tmp = h264bsdGetBits(pStrmData, 4);
if (tmp == END_OF_STREAM)
return(END_OF_STREAM);
pHrdParameters->cpbSizeScale = tmp;
for (i = 0; i < pHrdParameters->cpbCnt; i++)
{
/* bit_rate_value_minus1 in the range [0, 2^32 - 2] */
tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
&pHrdParameters->bitRateValue[i]);
if (tmp != HANTRO_OK)
return(tmp);
if (pHrdParameters->bitRateValue[i] > 4294967294U)
return(HANTRO_NOK);
pHrdParameters->bitRateValue[i]++;
/* this may result in overflow, but this value is not used for
* anything */
pHrdParameters->bitRateValue[i] *=
1 << (6 + pHrdParameters->bitRateScale);
/* cpb_size_value_minus1 in the range [0, 2^32 - 2] */
tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
&pHrdParameters->cpbSizeValue[i]);
if (tmp != HANTRO_OK)
return(tmp);
if (pHrdParameters->cpbSizeValue[i] > 4294967294U)
return(HANTRO_NOK);
pHrdParameters->cpbSizeValue[i]++;
/* this may result in overflow, but this value is not used for
* anything */
pHrdParameters->cpbSizeValue[i] *=
1 << (4 + pHrdParameters->cpbSizeScale);
tmp = h264bsdGetBits(pStrmData, 1);
if (tmp == END_OF_STREAM)
return(END_OF_STREAM);
pHrdParameters->cbrFlag[i] = (tmp == 1) ? HANTRO_TRUE : HANTRO_FALSE;
}
tmp = h264bsdGetBits(pStrmData, 5);
if (tmp == END_OF_STREAM)
return(END_OF_STREAM);
pHrdParameters->initialCpbRemovalDelayLength = tmp + 1;
tmp = h264bsdGetBits(pStrmData, 5);
if (tmp == END_OF_STREAM)
return(END_OF_STREAM);
pHrdParameters->cpbRemovalDelayLength = tmp + 1;
tmp = h264bsdGetBits(pStrmData, 5);
if (tmp == END_OF_STREAM)
return(END_OF_STREAM);
pHrdParameters->dpbOutputDelayLength = tmp + 1;
tmp = h264bsdGetBits(pStrmData, 5);
if (tmp == END_OF_STREAM)
return(END_OF_STREAM);
pHrdParameters->timeOffsetLength = tmp;
return(HANTRO_OK);
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,709 @@
/*------------------------------------------------------------------------------
-- --
-- This software is confidential and proprietary and may be used --
-- only as expressly authorized by a licensing agreement from --
-- --
-- Hantro Products Oy. --
-- --
-- (C) COPYRIGHT 2006 HANTRO PRODUCTS OY --
-- ALL RIGHTS RESERVED --
-- --
-- The entire notice above must be reproduced --
-- on all copies and should not be removed. --
-- --
--------------------------------------------------------------------------------
--
-- Description : Jpeg decoder header decoding source code
--
------------------------------------------------------------------------------
--
-- Version control information, please leave untouched.
--
-- $RCSfile: jpegdechdrs.c,v $
-- $Revision: 1.9 $
-- $Date: 2008/11/25 12:41:31 $
--
------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------
Table of contents
1. Include headers
2. External compiler flags
3. Module defines
4. Local function prototypes
5. Functions
- JpegDecDecodeFrame
- JpegDecDecodeQuantTables
- JpegDecDecodeHuffmanTables
------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------
1. Include headers
------------------------------------------------------------------------------*/
#include "jpegdechdrs.h"
#include "jpegdecutils.h"
#include "jpegdecmarkers.h"
#include "jpegdecinternal.h"
#include "jpegdecscan.h"
#include "jpegdecapi.h"
#include "dwl.h"
/*------------------------------------------------------------------------------
2. External compiler flags
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
3. Module defines
------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------
4. Local function prototypes
------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------
5. Functions
------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------
Function name: JpegDecDecodeFrame
Functional description:
Decodes frame headers
Inputs:
JpegDecContainer *pDecData Pointer to JpegDecContainer structure
Outputs:
OK/NOK
------------------------------------------------------------------------------*/
JpegDecRet JpegDecDecodeFrameHdr(JpegDecContainer * pDecData)
{
u32 i;
u32 width, height;
u32 tmp1, tmp2;
u32 Hmax = 0;
u32 Vmax = 0;
u32 size = 0;
JpegDecRet retCode;
retCode = JPEGDEC_OK;
/* frame header length */
pDecData->frame.Lf = JpegDecGet2Bytes(&(pDecData->stream));
/* check if there is enough data */
if(((pDecData->stream.readBits / 8) + pDecData->frame.Lf) >
pDecData->stream.streamLength)
return (JPEGDEC_STRM_ERROR);
/* Sample precision */
pDecData->frame.P = JpegDecGetByte(&(pDecData->stream));
if(pDecData->frame.P != 8)
{
JPEGDEC_TRACE_INTERNAL(("if ( pDecData->frame.P != 8)\n"));
return (JPEGDEC_UNSUPPORTED);
}
/* Number of Lines */
pDecData->frame.Y = JpegDecGet2Bytes(&(pDecData->stream));
if(pDecData->frame.Y < 1)
{
return (JPEGDEC_UNSUPPORTED);
}
pDecData->frame.hwY = pDecData->frame.Y;
/* round up to next multiple-of-16 */
pDecData->frame.hwY += 0xf;
pDecData->frame.hwY &= ~(0xf);
/* Number of samples per line */
pDecData->frame.X = JpegDecGet2Bytes(&(pDecData->stream));
if(pDecData->frame.X < 1)
{
return (JPEGDEC_UNSUPPORTED);
}
pDecData->frame.hwX = pDecData->frame.X;
/* round up to next multiple-of-16 */
pDecData->frame.hwX += 0xf;
pDecData->frame.hwX &= ~(0xf);
/* for internal() */
pDecData->info.X = pDecData->frame.hwX;
pDecData->info.Y = pDecData->frame.hwY;
/* check for minimum and maximum dimensions */
if(pDecData->frame.hwX < pDecData->minSupportedWidth ||
pDecData->frame.hwY < pDecData->minSupportedHeight ||
pDecData->frame.hwX > pDecData->maxSupportedWidth ||
pDecData->frame.hwY > pDecData->maxSupportedHeight ||
(pDecData->frame.hwX * pDecData->frame.hwY) >
pDecData->maxSupportedPixelAmount)
{
JPEGDEC_TRACE_INTERNAL(("FRAME: Unsupported size\n"));
return (JPEGDEC_UNSUPPORTED);
}
/* Number of components */
pDecData->frame.Nf = JpegDecGetByte(&(pDecData->stream));
if((pDecData->frame.Nf != 3) && (pDecData->frame.Nf != 1))
{
JPEGDEC_TRACE_INTERNAL(("pDecData->frame.Nf != 3 && pDecData->frame.Nf != 1\n"));
return (JPEGDEC_UNSUPPORTED);
}
/* save component specific data */
/* Nf == number of components */
for(i = 0; i < pDecData->frame.Nf; i++)
{
pDecData->frame.component[i].C = JpegDecGetByte(&(pDecData->stream));
if(i == 0) /* for the first component */
{
/* if first component id is something else than 1 (jfif) */
pDecData->scan.index = pDecData->frame.component[i].C;
}
else
{
/* if component ids 'jumps' */
if((pDecData->frame.component[i - 1].C + 1) !=
pDecData->frame.component[i].C)
{
JPEGDEC_TRACE_INTERNAL(("component ids 'jumps'\n"));
return (JPEGDEC_UNSUPPORTED);
}
}
tmp1 = JpegDecGetByte(&(pDecData->stream));
pDecData->frame.component[i].H = tmp1 >> 4;
if(pDecData->frame.component[i].H > Hmax)
{
Hmax = pDecData->frame.component[i].H;
}
pDecData->frame.component[i].V = tmp1 & 0xF;
if(pDecData->frame.component[i].V > Vmax)
{
Vmax = pDecData->frame.component[i].V;
}
pDecData->frame.component[i].Tq = JpegDecGetByte(&(pDecData->stream));
}
if(pDecData->frame.Nf == 1)
{
Hmax = Vmax = 1;
pDecData->frame.component[0].H = 1;
pDecData->frame.component[0].V = 1;
}
else if(Hmax == 0 || Vmax == 0)
{
JPEGDEC_TRACE_INTERNAL(("Hmax == 0 || Vmax == 0 \n"));
return (JPEGDEC_UNSUPPORTED);
}
/* JPEG_YCBCR411 horizontal size has to be multiple of 32 pels */
if(Hmax == 4 && (pDecData->frame.hwX & 0x1F))
{
/* round up to next multiple-of-32 */
pDecData->frame.hwX += 16;
pDecData->info.X = pDecData->frame.hwX;
/* check for minimum and maximum dimensions */
if(pDecData->frame.hwX > pDecData->maxSupportedWidth ||
(pDecData->frame.hwX * pDecData->frame.hwY) >
pDecData->maxSupportedPixelAmount)
{
JPEGDEC_TRACE_INTERNAL(("FRAME: Unsupported size\n"));
return (JPEGDEC_UNSUPPORTED);
}
}
/* set image pointers, calculate pixelPerRow for each component */
width = ((pDecData->frame.hwX + Hmax * 8 - 1) / (Hmax * 8)) * Hmax * 8;
height = ((pDecData->frame.hwY + Vmax * 8 - 1) / (Vmax * 8)) * Vmax * 8;
/* calculate numMcuInRow and numMcuInFrame */
ASSERT(Hmax != 0);
ASSERT(Vmax != 0);
pDecData->frame.numMcuInRow = width / (8 * Hmax);
pDecData->frame.numMcuInFrame = pDecData->frame.numMcuInRow *
(height / (8 * Vmax));
/* reset mcuNumbers */
pDecData->frame.mcuNumber = 0;
pDecData->frame.row = pDecData->frame.col = 0;
for(i = 0; i < pDecData->frame.Nf; i++)
{
ASSERT(i <= 2);
tmp1 = (width * pDecData->frame.component[i].H + Hmax - 1) / Hmax;
tmp2 = (height * pDecData->frame.component[i].V + Vmax - 1) / Vmax;
size += tmp1 * tmp2;
/* pixels per row */
pDecData->image.pixelsPerRow[i] = tmp1;
pDecData->image.columns[i] = tmp2;
pDecData->frame.numBlocks[i] =
(((pDecData->frame.hwX * pDecData->frame.component[i].H) / Hmax +
7) >> 3) * (((pDecData->frame.hwY *
pDecData->frame.component[i].V) / Vmax + 7) >> 3);
if(i == 0)
{
pDecData->image.sizeLuma = size;
}
}
pDecData->image.size = size;
pDecData->image.sizeChroma = size - pDecData->image.sizeLuma;
/* set mode & calculate rlc tmp size */
retCode = JpegDecMode(pDecData);
if(retCode != JPEGDEC_OK)
{
return (retCode);
}
return (JPEGDEC_OK);
}
/*------------------------------------------------------------------------------
Function name: JpegDecDecodeQuantTables
Functional description:
Decodes quantisation tables from the stream
Inputs:
JpegDecContainer *pDecData Pointer to JpegDecContainer structure
Outputs:
OK (0)
NOK (-1)
------------------------------------------------------------------------------*/
JpegDecRet JpegDecDecodeQuantTables(JpegDecContainer * pDecData)
{
u32 t, tmp, i;
StreamStorage *pStream = &(pDecData->stream);
pDecData->quant.Lq = JpegDecGet2Bytes(pStream);
/* check if there is enough data for tables */
if(((pStream->readBits / 8) + pDecData->quant.Lq) > pStream->streamLength)
return (JPEGDEC_STRM_ERROR);
t = 4;
while(t < pDecData->quant.Lq)
{
/* Tq value selects what table the components use */
/* read tables and write to decData->quant */
tmp = JpegDecGetByte(pStream);
t++;
/* supporting only 8 bits / sample */
if((tmp >> 4) != 0)
{
return (JPEGDEC_UNSUPPORTED);
}
tmp &= 0xF;
/* set the quantisation table pointer */
if(tmp == 0)
{
JPEGDEC_TRACE_INTERNAL(("qtable0\n"));
pDecData->quant.table = pDecData->quant.table0;
}
else if(tmp == 1)
{
JPEGDEC_TRACE_INTERNAL(("qtable1\n"));
pDecData->quant.table = pDecData->quant.table1;
}
else if(tmp == 2)
{
JPEGDEC_TRACE_INTERNAL(("qtable2\n"));
pDecData->quant.table = pDecData->quant.table2;
}
else if(tmp == 3)
{
JPEGDEC_TRACE_INTERNAL(("qtable3\n"));
pDecData->quant.table = pDecData->quant.table3;
}
else
{
return (JPEGDEC_UNSUPPORTED);
}
for(i = 0; i < 64; i++)
{
pDecData->quant.table[i] = JpegDecGetByte(pStream);
t++;
}
}
return (JPEGDEC_OK);
}
/*------------------------------------------------------------------------------
Function name: JpegDecDecodeHuffmanTables
Functional description:
Decodes huffman tables from the stream
Inputs:
DecData *JpegDecContainer Pointer to JpegDecContainer structure
Outputs:
OK (0)
NOK (-1)
------------------------------------------------------------------------------*/
JpegDecRet JpegDecDecodeHuffmanTables(JpegDecContainer * pDecData)
{
u32 i, len, Tc, Th, tmp;
i32 j;
StreamStorage *pStream = &(pDecData->stream);
pDecData->vlc.Lh = JpegDecGet2Bytes(pStream);
/* check if there is enough data for tables */
if(((pStream->readBits / 8) + pDecData->vlc.Lh) > pStream->streamLength)
return (JPEGDEC_STRM_ERROR);
/* four bytes already read in */
len = 4;
while(len < pDecData->vlc.Lh)
{
tmp = JpegDecGetByte(pStream);
len++;
Tc = tmp >> 4; /* Table class */
if(Tc != 0 && Tc != 1)
{
return (JPEGDEC_UNSUPPORTED);
}
Th = tmp & 0xF; /* Huffman table identifier */
/* only two tables in baseline allowed */
if((pDecData->frame.codingType == SOF0) && (Th > 1))
{
return (JPEGDEC_UNSUPPORTED);
}
/* four tables in progressive allowed */
if((pDecData->frame.codingType == SOF2) && (Th > 3))
{
return (JPEGDEC_UNSUPPORTED);
}
/* set the table pointer */
if(Tc)
{
/* Ac table */
switch (Th)
{
case 0:
JPEGDEC_TRACE_INTERNAL(("ac0\n"));
pDecData->vlc.table = &(pDecData->vlc.acTable0);
break;
case 1:
JPEGDEC_TRACE_INTERNAL(("ac1\n"));
pDecData->vlc.table = &(pDecData->vlc.acTable1);
break;
case 2:
JPEGDEC_TRACE_INTERNAL(("ac2\n"));
pDecData->vlc.table = &(pDecData->vlc.acTable2);
break;
case 3:
JPEGDEC_TRACE_INTERNAL(("ac3\n"));
pDecData->vlc.table = &(pDecData->vlc.acTable3);
break;
default:
return (JPEGDEC_UNSUPPORTED);
}
}
else
{
/* Dc table */
switch (Th)
{
case 0:
JPEGDEC_TRACE_INTERNAL(("dc0\n"));
pDecData->vlc.table = &(pDecData->vlc.dcTable0);
break;
case 1:
JPEGDEC_TRACE_INTERNAL(("dc1\n"));
pDecData->vlc.table = &(pDecData->vlc.dcTable1);
break;
case 2:
JPEGDEC_TRACE_INTERNAL(("dc2\n"));
pDecData->vlc.table = &(pDecData->vlc.dcTable2);
break;
case 3:
JPEGDEC_TRACE_INTERNAL(("dc3\n"));
pDecData->vlc.table = &(pDecData->vlc.dcTable3);
break;
default:
return (JPEGDEC_UNSUPPORTED);
}
}
tmp = 0;
/* read in the values of list BITS */
for(i = 0; i < 16; i++)
{
tmp += pDecData->vlc.table->bits[i] = JpegDecGetByte(pStream);
len++;
}
/* allocate memory for HUFFVALs */
if(pDecData->vlc.table->vals != NULL)
{
/* free previously reserved table */
DWLfree(pDecData->vlc.table->vals);
}
pDecData->vlc.table->vals = (u32 *) DWLmalloc(sizeof(u32) * tmp);
/* set the table length */
pDecData->vlc.table->tableLength = tmp;
/* read in the HUFFVALs */
for(i = 0; i < tmp; i++)
{
pDecData->vlc.table->vals[i] = JpegDecGetByte(pStream);
len++;
}
/* first and last lengths */
for(i = 0; i < 16; i++)
{
if(pDecData->vlc.table->bits[i] != 0)
{
pDecData->vlc.table->start = i;
break;
}
}
for(j = 15; j >= 0; j--)
{
if(pDecData->vlc.table->bits[j] != 0)
{
pDecData->vlc.table->last = ((u32) j + 1);
break;
}
}
}
return (JPEGDEC_OK);
}
/*------------------------------------------------------------------------------
Function name: JpegDecMode
Functional description:
check YCBCR mode
Inputs:
JpegDecContainer *pDecData Pointer to JpegDecContainer structure
Outputs:
OK/NOK
------------------------------------------------------------------------------*/
JpegDecRet JpegDecMode(JpegDecContainer * pDecData)
{
/* check input format */
if(pDecData->frame.Nf == 3)
{
/* JPEG_YCBCR420 */
if(pDecData->frame.component[0].H == 2 &&
pDecData->frame.component[0].V == 2 &&
pDecData->frame.component[1].H == 1 &&
pDecData->frame.component[1].V == 1 &&
pDecData->frame.component[2].H == 1 &&
pDecData->frame.component[2].V == 1)
{
pDecData->info.yCbCrMode = JPEGDEC_YUV420;
pDecData->info.X = pDecData->frame.hwX;
pDecData->info.Y = pDecData->frame.hwY;
/* calculate new output size if slice mode used */
if(pDecData->info.sliceMbSetValue)
{
/* Y */
pDecData->image.sizeLuma = (pDecData->info.X *
(pDecData->info.sliceMbSetValue *
16));
/* CbCr */
pDecData->image.sizeChroma = pDecData->image.sizeLuma / 2;
}
}
/* JPEG_YCBCR422 */
else if(pDecData->frame.component[0].H == 2 &&
pDecData->frame.component[0].V == 1 &&
pDecData->frame.component[1].H == 1 &&
pDecData->frame.component[1].V == 1 &&
pDecData->frame.component[2].H == 1 &&
pDecData->frame.component[2].V == 1)
{
pDecData->info.yCbCrMode = JPEGDEC_YUV422;
pDecData->info.X = (pDecData->frame.hwX);
pDecData->info.Y = (pDecData->frame.hwY);
/* check if fill needed */
if((pDecData->frame.Y & 0xF) && (pDecData->frame.Y & 0xF) <= 8)
pDecData->info.fillBottom = 1;
/* calculate new output size if slice mode used */
if(pDecData->info.sliceMbSetValue)
{
/* Y */
pDecData->image.sizeLuma = (pDecData->info.X *
(pDecData->info.sliceMbSetValue *
16));
/* CbCr */
pDecData->image.sizeChroma = pDecData->image.sizeLuma;
}
}
/* JPEG_YCBCR440 */
else if(pDecData->frame.component[0].H == 1 &&
pDecData->frame.component[0].V == 2 &&
pDecData->frame.component[1].H == 1 &&
pDecData->frame.component[1].V == 1 &&
pDecData->frame.component[2].H == 1 &&
pDecData->frame.component[2].V == 1)
{
pDecData->info.yCbCrMode = JPEGDEC_YUV440;
pDecData->info.X = (pDecData->frame.hwX);
pDecData->info.Y = (pDecData->frame.hwY);
/* check if fill needed */
if((pDecData->frame.X & 0xF) && (pDecData->frame.X & 0xF) <= 8)
pDecData->info.fillRight = 1;
/* calculate new output size if slice mode used */
if(pDecData->info.sliceMbSetValue)
{
/* Y */
pDecData->image.sizeLuma = (pDecData->info.X *
(pDecData->info.sliceMbSetValue *
16));
/* CbCr */
pDecData->image.sizeChroma = pDecData->image.sizeLuma;
}
}
/* JPEG_YCBCR444 : NOT SUPPORTED */
else if(pDecData->frame.component[0].H == 1 &&
pDecData->frame.component[0].V == 1 &&
pDecData->frame.component[1].H == 1 &&
pDecData->frame.component[1].V == 1 &&
pDecData->frame.component[2].H == 1 &&
pDecData->frame.component[2].V == 1)
{
pDecData->info.yCbCrMode = JPEGDEC_YUV444;
pDecData->info.X = pDecData->frame.hwX;
pDecData->info.Y = pDecData->frame.hwY;
/* check if fill needed */
if((pDecData->frame.X & 0xF) && (pDecData->frame.X & 0xF) <= 8)
pDecData->info.fillRight = 1;
if((pDecData->frame.Y & 0xF) && (pDecData->frame.Y & 0xF) <= 8)
pDecData->info.fillBottom = 1;
/* calculate new output size if slice mode used */
if(pDecData->info.sliceMbSetValue)
{
/* Y */
pDecData->image.sizeLuma = (pDecData->info.X *
(pDecData->info.sliceMbSetValue *
16));
/* CbCr */
pDecData->image.sizeChroma = pDecData->image.sizeLuma * 2;
}
}
/* JPEG_YCBCR411 */
else if(pDecData->frame.component[0].H == 4 &&
pDecData->frame.component[0].V == 1 &&
pDecData->frame.component[1].H == 1 &&
pDecData->frame.component[1].V == 1 &&
pDecData->frame.component[2].H == 1 &&
pDecData->frame.component[2].V == 1)
{
pDecData->info.yCbCrMode = JPEGDEC_YUV411;
pDecData->info.X = (pDecData->frame.hwX);
pDecData->info.Y = (pDecData->frame.hwY);
/* check if fill needed */
if((pDecData->frame.Y & 0xF) && (pDecData->frame.Y & 0xF) <= 8)
pDecData->info.fillBottom = 1;
/* calculate new output size if slice mode used */
if(pDecData->info.sliceMbSetValue)
{
/* Y */
pDecData->image.sizeLuma = (pDecData->info.X *
(pDecData->info.sliceMbSetValue *
16));
/* CbCr */
pDecData->image.sizeChroma = pDecData->image.sizeLuma / 2;
}
}
else
{
return (JPEGDEC_UNSUPPORTED);
}
}
else if(pDecData->frame.Nf == 1)
{
/* 4:0:0 */
if((pDecData->frame.component[0].V == 1) ||
(pDecData->frame.component[0].H == 1))
{
pDecData->info.yCbCrMode = JPEGDEC_YUV400;
pDecData->info.X = (pDecData->frame.hwX);
pDecData->info.Y = (pDecData->frame.hwY);
/* check if fill needed */
if((pDecData->frame.X & 0xF) && (pDecData->frame.X & 0xF) <= 8)
pDecData->info.fillRight = 1;
if((pDecData->frame.Y & 0xF) && (pDecData->frame.Y & 0xF) <= 8)
pDecData->info.fillBottom = 1;
/* calculate new output size if slice mode used */
if(pDecData->info.sliceMbSetValue)
{
/* Y */
pDecData->image.sizeLuma =
((((pDecData->info.X +
15) / 16) * 16) * (pDecData->info.sliceMbSetValue *
16));
/* CbCr */
pDecData->image.sizeChroma = 0;
}
}
else
{
return (JPEGDEC_UNSUPPORTED);
}
}
else
{
return (JPEGDEC_UNSUPPORTED);
}
/* save the original sampling format for progressive use */
pDecData->info.yCbCrModeOrig = pDecData->info.yCbCrMode;
return (JPEGDEC_OK);
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,349 @@
/*------------------------------------------------------------------------------
-- --
-- This software is confidential and proprietary and may be used --
-- only as expressly authorized by a licensing agreement from --
-- --
-- Hantro Products Oy. --
-- --
-- (C) COPYRIGHT 2006 HANTRO PRODUCTS OY --
-- ALL RIGHTS RESERVED --
-- --
-- The entire notice above must be reproduced --
-- on all copies and should not be removed. --
-- --
--------------------------------------------------------------------------------
--
-- Description : jpeg scan decode source
--
------------------------------------------------------------------------------
--
-- Version control information, please leave untouched.
--
-- $RCSfile: jpegdecscan.c,v $
-- $Revision: 1.12 $
-- $Date: 2008/10/14 12:00:55 $
--
------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------
Table of contents
1. Include headers
2. External compiler flags
3. Module defines
4. Local function prototypes
5. Functions
- JpegDecDecodeScan
- JpegDecDecodeScanHeader
- JpegDecDecodeBaselineScan
- JpegDecDecodeProgressiveScan
- JpegDecDecodeBaselineBlock
------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------
1. Include headers
------------------------------------------------------------------------------*/
#include "jpegdecutils.h"
#include "jpegdecinternal.h"
#include "jpegdecmarkers.h"
#include "jpegdecscan.h"
#include "dwl.h"
/*------------------------------------------------------------------------------
2. External compiler flags
--------------------------------------------------------------------------------
_DTRACE: define this flag to print trace information to stdout
--------------------------------------------------------------------------------
3. Module defines
------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------
4. Local function prototypes
------------------------------------------------------------------------------*/
JpegDecRet JpegDecDecodeScanHeader(JpegDecContainer *);
/*------------------------------------------------------------------------------
5. Functions
------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------
Function name: JpegDecDecodeScan
Functional description:
Handles the top level control of scan decoding
Inputs:
JpegDecContainer *pDecData Pointer to JpegDecContainer structure
Outputs:
OK (0)
NOK (-1)
------------------------------------------------------------------------------*/
JpegDecRet JpegDecDecodeScan(JpegDecContainer * pDecData)
{
JpegDecRet retCode; /* Returned code container */
retCode = JPEGDEC_ERROR;
retCode = JpegDecDecodeScanHeader(pDecData);
if(retCode != JPEGDEC_OK)
{
return (retCode);
}
JPEGDEC_TRACE_INTERNAL(("SCAN: Allocate residual buffer\n"));
/* Allocate buffers if not done already */
if(!pDecData->info.allocated)
{
retCode = JpegDecAllocateResidual(pDecData);
if(retCode != JPEGDEC_OK)
{
JPEGDEC_TRACE_INTERNAL(("SCAN: ALLOCATE ERROR\n"));
return (retCode);
}
/* update */
pDecData->info.allocated = 1;
}
JPEGDEC_TRACE_INTERNAL(("SCAN: Scan rlc data\n"));
JPEGDEC_TRACE_INTERNAL(("SCAN: MODE: %d\n", pDecData->frame.codingType));
return (JPEGDEC_OK);
}
/*------------------------------------------------------------------------------
Function name: JpegDecDecodeScanHeader
Functional description:
Decodes scan headers
Inputs:
JpegDecContainer *pDecData Pointer to JpegDecContainer structure
Outputs:
OK (0)
NOK (-1)
------------------------------------------------------------------------------*/
JpegDecRet JpegDecDecodeScanHeader(JpegDecContainer * pDecData)
{
u32 i;
u32 tmp;
StreamStorage *pStream = &(pDecData->stream);
pDecData->scan.Ls = JpegDecGet2Bytes(pStream);
/* check if there is enough data */
if(((pStream->readBits / 8) + pDecData->scan.Ls) > pStream->streamLength)
return (JPEGDEC_STRM_ERROR);
pDecData->scan.Ns = JpegDecGetByte(pStream);
pDecData->info.fillX = pDecData->info.fillY = 0;
if(pDecData->scan.Ns == 1)
{
/* Reset to non-interleaved baseline operation type */
if(pDecData->info.operationType == JPEGDEC_BASELINE &&
pDecData->info.yCbCrMode != JPEGDEC_YUV400)
pDecData->info.operationType = JPEGDEC_NONINTERLEAVED;
tmp = JpegDecGetByte(&(pDecData->stream));
pDecData->frame.cIndex = tmp - 1;
pDecData->info.componentId = pDecData->frame.cIndex;
pDecData->scan.Cs[pDecData->frame.cIndex] = tmp;
tmp = JpegDecGetByte(pStream);
pDecData->scan.Td[pDecData->frame.cIndex] = tmp >> 4;
pDecData->scan.Ta[pDecData->frame.cIndex] = tmp & 0x0F;
/* check/update component info */
if(pDecData->frame.Nf == 3)
{
pDecData->info.fillRight = 0;
pDecData->info.fillBottom = 0;
pDecData->info.
pfNeeded[pDecData->scan.Cs[pDecData->frame.cIndex] - 1] = 0;
if(pDecData->scan.Cs[pDecData->frame.cIndex] == 2 ||
pDecData->scan.Cs[pDecData->frame.cIndex] == 3)
{
if(pDecData->info.operationType == JPEGDEC_PROGRESSIVE ||
pDecData->info.operationType == JPEGDEC_NONINTERLEAVED ||
pDecData->info.nonInterleavedScanReady)
{
if(pDecData->info.yCbCrModeOrig == JPEGDEC_YUV420)
{
pDecData->info.X = pDecData->frame.hwX >> 1;
pDecData->info.Y = pDecData->frame.hwY >> 1;
}
else if(pDecData->info.yCbCrModeOrig == JPEGDEC_YUV422)
{
pDecData->info.X = pDecData->frame.hwX >> 1;
}
else if(pDecData->info.yCbCrModeOrig == JPEGDEC_YUV440)
{
pDecData->info.Y = pDecData->frame.hwY >> 1;
}
else
{
pDecData->info.yCbCrMode = 0;
return (JPEGDEC_UNSUPPORTED);
}
}
pDecData->info.yCbCrMode = 0;
}
else if(pDecData->scan.Cs[pDecData->frame.cIndex] == 1) /* YCbCr 4:2:0 */
{
pDecData->info.X = pDecData->frame.hwX;
pDecData->info.Y = pDecData->frame.hwY;
if(pDecData->info.yCbCrMode == JPEGDEC_YUV420)
{
pDecData->info.yCbCrMode = 1;
}
else if(pDecData->info.yCbCrMode == JPEGDEC_YUV422)
{
pDecData->info.yCbCrMode = 0;
if(pDecData->frame.cIndex == 0)
{
JPEGDEC_TRACE_INTERNAL(("SCAN: #YUV422 FLAG\n"));
pDecData->info.yCbCr422 = 1;
}
}
else if(pDecData->info.yCbCrMode == JPEGDEC_YUV444)
{
pDecData->info.yCbCrMode = 0;
return (JPEGDEC_UNSUPPORTED);
}
}
else
{
pDecData->info.yCbCrMode = 0;
return (JPEGDEC_UNSUPPORTED);
}
if(pDecData->info.X & 0xF)
{
pDecData->info.X += 8;
pDecData->info.fillX = 1;
}
else if((pDecData->scan.Cs[pDecData->frame.cIndex] == 1 ||
pDecData->info.yCbCrModeOrig == JPEGDEC_YUV440) &&
(pDecData->frame.X & 0xF) && (pDecData->frame.X & 0xF) <= 8)
{
pDecData->info.fillRight = 1;
}
if(pDecData->info.Y & 0xF)
{
pDecData->info.Y += 8;
pDecData->info.fillY = 1;
}
else if((pDecData->scan.Cs[pDecData->frame.cIndex] == 1 ||
pDecData->info.yCbCrModeOrig == JPEGDEC_YUV422) &&
(pDecData->frame.Y & 0xF) && (pDecData->frame.Y & 0xF) <= 8)
{
pDecData->info.fillBottom = 1;
}
}
else if(pDecData->frame.Nf == 1)
{
JPEGDEC_TRACE_INTERNAL(("SCAN: #YUV422 FLAG\n"));
pDecData->info.yCbCr422 = 0;
}
/* decoding info */
if(pDecData->info.operationType == JPEGDEC_PROGRESSIVE ||
pDecData->info.operationType == JPEGDEC_NONINTERLEAVED)
{
pDecData->info.yCbCrMode = 0;
}
}
else
{
for(i = 0; i < pDecData->scan.Ns; i++)
{
pDecData->scan.Cs[i] = JpegDecGetByte(&(pDecData->stream));
tmp = JpegDecGetByte(pStream);
pDecData->scan.Td[i] = tmp >> 4; /* which DC table */
pDecData->scan.Ta[i] = tmp & 0x0F; /* which AC table */
pDecData->info.pfNeeded[i] = 1;
}
pDecData->info.X = pDecData->frame.hwX;
pDecData->info.Y = pDecData->frame.hwY;
pDecData->frame.cIndex = 0;
pDecData->info.yCbCrMode = pDecData->info.yCbCrModeOrig;
}
pDecData->scan.Ss = JpegDecGetByte(pStream);
pDecData->scan.Se = JpegDecGetByte(pStream);
tmp = JpegDecGetByte(pStream);
pDecData->scan.Ah = tmp >> 4;
pDecData->scan.Al = tmp & 0x0F;
if(pDecData->frame.codingType == SOF0)
{
/* baseline */
if(pDecData->scan.Ss != 0)
return (JPEGDEC_UNSUPPORTED);
if(pDecData->scan.Se != 63)
return (JPEGDEC_UNSUPPORTED);
if(pDecData->scan.Ah != 0)
return (JPEGDEC_UNSUPPORTED);
if(pDecData->scan.Al != 0)
return (JPEGDEC_UNSUPPORTED);
/* update scan decoding parameters */
/* interleaved/non-interleaved */
if(pDecData->info.operationType == JPEGDEC_BASELINE)
pDecData->info.nonInterleaved = 0;
else
pDecData->info.nonInterleaved = 1;
/* decoding info */
if((pDecData->frame.Nf == 3 && pDecData->scan.Ns == 1) ||
(pDecData->frame.Nf == 1 && pDecData->scan.Ns == 1))
pDecData->info.amountOfQTables = 1;
else
pDecData->info.amountOfQTables = 3;
}
if(pDecData->frame.codingType == SOF2)
{
/* progressive */
if(pDecData->scan.Ss == 0 && pDecData->scan.Se != 0)
return (JPEGDEC_UNSUPPORTED);
if(/*pDecData->scan.Ah < 0 || */pDecData->scan.Ah > 13)
return (JPEGDEC_UNSUPPORTED);
if(/*pDecData->scan.Al < 0 || */pDecData->scan.Al > 13)
return (JPEGDEC_UNSUPPORTED);
/* update scan decoding parameters */
/* TODO! What if 2 components, possible??? */
/* interleaved/non-interleaved */
if(pDecData->scan.Ns == 1)
{
pDecData->info.nonInterleaved = 1;
/* component ID */
pDecData->info.componentId = pDecData->frame.cIndex;
pDecData->info.amountOfQTables = 1;
}
else
{
pDecData->info.nonInterleaved = 0;
/* component ID ==> set to luma ==> interleaved */
pDecData->info.componentId = 0;
pDecData->info.amountOfQTables = 3;
}
}
return (JPEGDEC_OK);
}

View File

@ -0,0 +1,288 @@
/*------------------------------------------------------------------------------
-- --
-- This software is confidential and proprietary and may be used --
-- only as expressly authorized by a licensing agreement from --
-- --
-- Hantro Products Oy. --
-- --
-- (C) COPYRIGHT 2006 HANTRO PRODUCTS OY --
-- ALL RIGHTS RESERVED --
-- --
-- The entire notice above must be reproduced --
-- on all copies and should not be removed. --
-- --
--------------------------------------------------------------------------------
--
-- Description :Jpeg Decoder utils
--
------------------------------------------------------------------------------
--
-- Version control information, please leave untouched.
--
-- $RCSfile: jpegdecutils.c,v $
-- $Revision: 1.1 $
-- $Date: 2007/03/30 05:44:50 $
--
------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------
Table of contents
1. Include headers
2. External compiler flags
3. Module defines
4. Local function prototypes
5. Functions
- JpegDecGetByte
- JpegDecGet2Bytes
- JpegDecShowBits
- JpegDecFlushBits
------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------
1. Include headers
------------------------------------------------------------------------------*/
#include "jpegdecutils.h"
#include "jpegdecmarkers.h"
/*------------------------------------------------------------------------------
2. External compiler flags
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
3. Module defines
------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------
4. Local function prototypes
------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------
5. Functions
------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------
Function name: JpegDecGetByte
Functional description:
Reads one byte (8 bits) from stream and returns the bits
Note! This function does not skip the 0x00 byte if the previous
byte value was 0xFF!!!
Inputs:
StreamStorage *pStream Pointer to structure
Outputs:
Returns 8 bit value if ok
else returns STRM_ERROR (0xFFFFFFFF)
------------------------------------------------------------------------------*/
u32 JpegDecGetByte(StreamStorage * pStream)
{
u32 tmp;
if((pStream->readBits + 8) > (8 * pStream->streamLength))
return (STRM_ERROR);
tmp = *(pStream->pCurrPos)++;
tmp = (tmp << 8) | *(pStream->pCurrPos);
tmp = (tmp >> (8 - pStream->bitPosInByte)) & 0xFF;
pStream->readBits += 8;
return (tmp);
}
/*------------------------------------------------------------------------------
Function name: JpegDecGet2Bytes
Functional description:
Reads two bytes (16 bits) from stream and returns the bits
Note! This function does not skip the 0x00 byte if the previous
byte value was 0xFF!!!
Inputs:
StreamStorage *pStream Pointer to structure
Outputs:
Returns 16 bit value
------------------------------------------------------------------------------*/
u32 JpegDecGet2Bytes(StreamStorage * pStream)
{
u32 tmp;
if((pStream->readBits + 16) > (8 * pStream->streamLength))
return (STRM_ERROR);
tmp = *(pStream->pCurrPos)++;
tmp = (tmp << 8) | *(pStream->pCurrPos)++;
tmp = (tmp << 8) | *(pStream->pCurrPos);
tmp = (tmp >> (8 - pStream->bitPosInByte)) & 0xFFFF;
pStream->readBits += 16;
return (tmp);
}
/*------------------------------------------------------------------------------
Function name: JpegDecShowBits
Functional description:
Reads 32 bits from stream and returns the bits, does not update
stream pointers. If there are not enough bits in data buffer it
reads the rest of the data buffer bits and fills the lsb of return
value with zero bits.
Note! This function will skip the byte valued 0x00 if the previous
byte value was 0xFF!!!
Inputs:
StreamStorage *pStream Pointer to structure
Outputs:
Returns 32 bit value
------------------------------------------------------------------------------*/
u32 JpegDecShowBits(StreamStorage * pStream)
{
i32 bits;
u32 readBits;
u32 out = 0;
u8 *pData = pStream->pCurrPos;
/* bits left in buffer */
bits = (i32) (8 * pStream->streamLength - pStream->readBits);
if(!bits)
return (0);
readBits = 0;
do
{
if(pData > pStream->pStartOfStream)
{
/* FF 00 bytes in stream -> jump over 00 byte */
if((pData[-1] == 0xFF) && (pData[0] == 0x00))
{
pData++;
bits -= 8;
}
}
if(readBits == 32 && pStream->bitPosInByte)
{
out <<= pStream->bitPosInByte;
out |= *pData >> (8 - pStream->bitPosInByte);
readBits = 0;
break;
}
out = (out << 8) | *pData++;
readBits += 8;
bits -= 8;
}
while(readBits < (32 + pStream->bitPosInByte) && bits > 0);
if(bits <= 0 &&
((readBits + pStream->readBits) >= (pStream->streamLength * 8)))
{
/* not enough bits in stream, fill with zeros */
out = (out << (32 - (readBits - pStream->bitPosInByte)));
}
return (out);
}
/*------------------------------------------------------------------------------
Function name: JpegDecFlushBits
Functional description:
Updates stream pointers, flushes bits from stream
Note! This function will skip the byte valued 0x00 if the previous
byte value was 0xFF!!!
Inputs:
StreamStorage *pStream Pointer to structure
u32 bits Number of bits to be flushed
Outputs:
OK
STRM_ERROR
------------------------------------------------------------------------------*/
u32 JpegDecFlushBits(StreamStorage * pStream, u32 bits)
{
u32 tmp;
u32 extraBits = 0;
if((pStream->readBits + bits) > (8 * pStream->streamLength))
{
/* there are not so many bits left in buffer */
/* stream pointers to the end of the stream */
/* and return value STRM_ERROR */
pStream->readBits = 8 * pStream->streamLength;
pStream->bitPosInByte = 0;
pStream->pCurrPos = pStream->pStartOfStream + pStream->streamLength;
return (STRM_ERROR);
}
else
{
tmp = 0;
while(tmp < bits)
{
if(bits - tmp < 8)
{
if((8 - pStream->bitPosInByte) > (bits - tmp))
{
/* inside one byte */
pStream->bitPosInByte += bits - tmp;
tmp = bits;
}
else
{
if(pStream->pCurrPos[0] == 0xFF &&
pStream->pCurrPos[1] == 0x00)
{
extraBits += 8;
pStream->pCurrPos += 2;
}
else
{
pStream->pCurrPos++;
}
tmp += 8 - pStream->bitPosInByte;
pStream->bitPosInByte = 0;
pStream->bitPosInByte = bits - tmp;
tmp = bits;
}
}
else
{
tmp += 8;
if(pStream->appnFlag)
{
pStream->pCurrPos++;
}
else
{
if(pStream->pCurrPos[0] == 0xFF &&
pStream->pCurrPos[1] == 0x00)
{
extraBits += 8;
pStream->pCurrPos += 2;
}
else
{
pStream->pCurrPos++;
}
}
}
}
/* update stream pointers */
pStream->readBits += bits + extraBits;
return (OK);
}
}

View File

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

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,130 @@
/*------------------------------------------------------------------------------
-- --
-- This software is confidential and proprietary and may be used --
-- only as expressly authorized by a licensing agreement from --
-- --
-- Hantro Products Oy. --
-- --
-- (C) COPYRIGHT 2006 HANTRO PRODUCTS OY --
-- ALL RIGHTS RESERVED --
-- --
-- The entire notice above must be reproduced --
-- on all copies and should not be removed. --
-- --
--------------------------------------------------------------------------------
--
-- Description :
--
--------------------------------------------------------------------------------
--
-- Version control information, please leave untouched.
--
-- $RCSfile: regdrv.c,v $
-- $Revision: 1.6 $
-- $Date: 2008/04/24 11:49:29 $
--
------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------
Include headers
------------------------------------------------------------------------------*/
#include "regdrv.h"
/*------------------------------------------------------------------------------
External compiler flags
------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------
Module defines
------------------------------------------------------------------------------*/
#ifdef _ASSERT_USED
#ifndef ASSERT
#include <assert.h>
#define ASSERT(expr) assert(expr)
#endif
#else
#define ASSERT(expr)
#endif
static const u32 regMask[33] = { 0x00000000,
0x00000001, 0x00000003, 0x00000007, 0x0000000F,
0x0000001F, 0x0000003F, 0x0000007F, 0x000000FF,
0x000001FF, 0x000003FF, 0x000007FF, 0x00000FFF,
0x00001FFF, 0x00003FFF, 0x00007FFF, 0x0000FFFF,
0x0001FFFF, 0x0003FFFF, 0x0007FFFF, 0x000FFFFF,
0x001FFFFF, 0x003FFFFF, 0x007FFFFF, 0x00FFFFFF,
0x01FFFFFF, 0x03FFFFFF, 0x07FFFFFF, 0x0FFFFFFF,
0x1FFFFFFF, 0x3FFFFFFF, 0x7FFFFFFF, 0xFFFFFFFF
};
/* { SWREG, BITS, POSITION } */
static const u32 hwDecRegSpec[HWIF_LAST_REG + 1][3] = {
/* include script-generated part */
#include "8170table.h"
/* HWIF_DEC_IRQ_STAT */ {1, 7, 12},
/* HWIF_PP_IRQ_STAT */ {60, 2, 12},
/* dummy entry */ {0, 0, 0}
};
/*------------------------------------------------------------------------------
Local function prototypes
------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------
Functions
------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------
Function name: SetDecRegister
Functional description:
Inputs:
Outputs:
Returns:
------------------------------------------------------------------------------*/
void SetDecRegister(u32 * regBase, u32 id, u32 value)
{
u32 tmp;
ASSERT(id < HWIF_LAST_REG);
tmp = regBase[hwDecRegSpec[id][0]];
tmp &= ~(regMask[hwDecRegSpec[id][1]] << hwDecRegSpec[id][2]);
tmp |= (value & regMask[hwDecRegSpec[id][1]]) << hwDecRegSpec[id][2];
regBase[hwDecRegSpec[id][0]] = tmp;
}
/*------------------------------------------------------------------------------
Function name: GetDecRegister
Functional description:
Inputs:
Outputs:
Returns:
------------------------------------------------------------------------------*/
u32 GetDecRegister(const u32 * regBase, u32 id)
{
u32 tmp;
ASSERT(id < HWIF_LAST_REG);
tmp = regBase[hwDecRegSpec[id][0]];
tmp = tmp >> hwDecRegSpec[id][2];
tmp &= regMask[hwDecRegSpec[id][1]];
return (tmp);
}

View File

@ -0,0 +1,103 @@
/*------------------------------------------------------------------------------
-- --
-- This software is confidential and proprietary and may be used --
-- only as expressly authorized by a licensing agreement from --
-- --
-- Hantro Products Oy. --
-- --
-- (C) COPYRIGHT 2006 HANTRO PRODUCTS OY --
-- ALL RIGHTS RESERVED --
-- --
-- The entire notice above must be reproduced --
-- on all copies and should not be removed. --
-- --
--------------------------------------------------------------------------------
--
-- Abstract : Stream decoding utilities
--
--------------------------------------------------------------------------------
--
-- Version control information, please leave untouched.
--
-- $RCSfile: tiledref.c,v $
-- $Date: 2011/01/17 13:17:06 $
-- $Revision: 1.4 $
--
------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------
Table of context
1. Include headers
2. External identifiers
3. Module defines
4. Module identifiers
5. Fuctions
------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------
1. Include headers
------------------------------------------------------------------------------*/
#include "tiledref.h"
#include "regdrv.h"
/*------------------------------------------------------------------------------
2. External identifiers
------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------
3. Module defines
------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------
4. Module indentifiers
------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------
DecSetupTiledReference
Enable/disable tiled reference mode on HW. See inside function for
disable criterias.
Returns tile mode.
------------------------------------------------------------------------------*/
u32 DecSetupTiledReference( u32 *regBase, u32 tiledModeSupport, u32 interlacedStream )
{
u32 tiledAllowed = 1;
u32 mode = 0;
if(!tiledModeSupport)
{
SetDecRegister(regBase, HWIF_TILED_MODE_MSB, 0 );
SetDecRegister(regBase, HWIF_TILED_MODE_LSB, 0 );
return TILED_REF_NONE;
}
/* disable for interlaced streams */
if(interlacedStream)
tiledAllowed = 0;
/* if tiled mode allowed, pick a tile mode that suits us best (pretty easy
* as we currently only support 8x4 */
if(tiledAllowed)
{
if(tiledModeSupport == 1 )
{
mode = TILED_REF_8x4;
}
}
else
{
mode = TILED_REF_NONE;
}
/* Setup HW registers */
SetDecRegister(regBase, HWIF_TILED_MODE_MSB, (mode >> 1) & 0x1 );
SetDecRegister(regBase, HWIF_TILED_MODE_LSB, mode & 0x1 );
return mode;
}

View File

@ -0,0 +1,427 @@
/*------------------------------------------------------------------------------
-- --
-- This software is confidential and proprietary and may be used --
-- only as expressly authorized by a licensing agreement from --
-- --
-- Hantro Products Oy. --
-- --
-- (C) COPYRIGHT 2006 HANTRO PRODUCTS OY --
-- ALL RIGHTS RESERVED --
-- --
-- The entire notice above must be reproduced --
-- on all copies and should not be removed. --
-- --
--------------------------------------------------------------------------------
--
-- Abstract : Stream decoding utilities
--
--------------------------------------------------------------------------------
--
-- Version control information, please leave untouched.
--
-- $RCSfile: workaround.c,v $
-- $Date: 2010/07/23 09:19:10 $
-- $Revision: 1.7 $
--
------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------
Table of context
1. Include headers
2. External identifiers
3. Module defines
4. Module identifiers
5. Fuctions
5.1 StrmDec_GetBits
5.2 StrmDec_ShowBits
5.3 StrmDec_ShowBitsAligned
5.4 StrmDec_FlushBits
5.5 StrmDec_NextStartCode
5.6 StrmDec_FindSync
5.7 StrmDec_GetStartCode
5.8 StrmDec_NumBits
5.9 StrmDec_UnFlushBits
------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------
1. Include headers
------------------------------------------------------------------------------*/
#include "workaround.h"
#include "dwl.h"
/*------------------------------------------------------------------------------
2. External identifiers
------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------
3. Module defines
------------------------------------------------------------------------------*/
#define MAGIC_WORD_LENGTH (8)
#define MB_OFFSET (4)
static const u8 magicWord[MAGIC_WORD_LENGTH] = "Rosebud\0";
/*------------------------------------------------------------------------------
4. Module indentifiers
------------------------------------------------------------------------------*/
static u32 GetMbOffset( u32 mbNum, u32 vopWidth, u32 vopHeight );
/*------------------------------------------------------------------------------
5.1 Function name: GetMbOffset
Purpose:
Input:
Output:
------------------------------------------------------------------------------*/
u32 GetMbOffset( u32 mbNum, u32 vopWidth, u32 vopHeight )
{
u32 mbRow, mbCol;
u32 offset;
mbRow = mbNum / vopWidth;
mbCol = mbNum % vopWidth;
offset = mbRow*16*16*vopWidth + mbCol*16;
return offset;
}
/*------------------------------------------------------------------------------
5.1 Function name: PrepareStuffingWorkaround
Purpose:
Input:
Output:
------------------------------------------------------------------------------*/
void StuffMacroblock( u32 mbNum, u8 * pDecOut, u8 *pRefPic, u32 vopWidth,
u32 vopHeight )
{
u32 pixWidth;
u32 mbRow, mbCol;
u32 offset;
u32 lumaSize;
u8 *pSrc;
u8 *pDst;
u32 x, y;
pixWidth = 16*vopWidth;
mbRow = mbNum / vopWidth;
mbCol = mbNum % vopWidth;
offset = mbRow*16*pixWidth + mbCol*16;
lumaSize = 256*vopWidth*vopHeight;
if(pRefPic)
{
pDst = pDecOut;
pSrc = pRefPic;
pDst += offset;
pSrc += offset;
/* Copy luma data */
for( y = 0 ; y < 16 ; ++y )
{
for( x = 0 ; x < 16 ; ++x )
{
pDst[x] = pSrc[x];
}
pDst += pixWidth;
pSrc += pixWidth;
}
/* Chroma data */
offset = mbRow*8*pixWidth + mbCol*16;
pDst = pDecOut;
pSrc = pRefPic;
pDst += lumaSize;
pSrc += lumaSize;
pDst += offset;
pSrc += offset;
for( y = 0 ; y < 8 ; ++y )
{
for( x = 0 ; x < 16 ; ++x )
{
pDst[x] = pSrc[x];
}
pDst += pixWidth;
pSrc += pixWidth;
}
}
else
{
pDst = pDecOut + offset;
/* Copy luma data */
for( y = 0 ; y < 16 ; ++y )
{
for( x = 0 ; x < 16 ; ++x )
{
i32 tmp;
if( mbCol )
tmp = pDst[x-pixWidth] + pDst[x-1] - pDst[x-pixWidth-1];
else
tmp = pDst[x-pixWidth];
if( tmp < 0 ) tmp = 0;
else if ( tmp > 255 ) tmp = 255;
pDst[x] = tmp;
}
pDst += pixWidth;
}
/* Chroma data */
offset = mbRow*8*pixWidth + mbCol*16;
pDst = pDecOut + lumaSize + offset;
for( y = 0 ; y < 8 ; ++y )
{
for( x = 0 ; x < 16 ; ++x )
{
i32 tmp;
if( mbCol )
tmp = pDst[x-pixWidth] + pDst[x-2] - pDst[x-pixWidth-2];
else
tmp = pDst[x-pixWidth];
if( tmp < 0 ) tmp = 0;
else if ( tmp > 255 ) tmp = 255;
pDst[x] = tmp;
}
pDst += pixWidth;
}
}
}
/*------------------------------------------------------------------------------
5.1 Function name: PrepareStuffingWorkaround
Purpose:
Input:
Output:
------------------------------------------------------------------------------*/
void PrepareStuffingWorkaround( u8 *pDecOut, u32 vopWidth, u32 vopHeight )
{
u32 i;
u8 * pBase;
pBase = pDecOut + GetMbOffset(vopWidth*vopHeight - MB_OFFSET,
vopWidth, vopHeight );
for( i = 0 ; i < MAGIC_WORD_LENGTH ; ++i )
pBase[i] = magicWord[i];
}
/*------------------------------------------------------------------------------
5.1 Function name: ProcessStuffingWorkaround
Purpose: Check bytes written in PrepareStuffingWorkaround(). If bytes
match magic word, then error happened earlier on in the picture.
If bytes mismatch, then HW got to end of picture and error
interrupt is most likely because of faulty stuffing. In this
case we either conceal tail end of the frame or copy it from
previous frame.
Input:
Output:
HANTRO_TRUE
HANTRO_FALSE
------------------------------------------------------------------------------*/
u32 ProcessStuffingWorkaround( u8 * pDecOut, u8 * pRefPic, u32 vopWidth,
u32 vopHeight )
{
u32 i;
u8 * pBase;
u32 numMbs;
u32 match = HANTRO_TRUE;
numMbs = vopWidth*vopHeight;
pBase = pDecOut + GetMbOffset(numMbs - MB_OFFSET, vopWidth, vopHeight );
for( i = 0 ; i < MAGIC_WORD_LENGTH && match ; ++i )
if( pBase[i] != magicWord[i] )
match = HANTRO_FALSE;
/* If 4th last macroblock is overwritten, then assume it's a stuffing
* error. Copy remaining three macroblocks from previous ref frame. */
if( !match )
{
for ( i = 1+numMbs - MB_OFFSET ; i < numMbs ; ++i )
{
StuffMacroblock( i, pDecOut, pRefPic, vopWidth, vopHeight );
}
}
return match ? HANTRO_FALSE : HANTRO_TRUE;
}
/*------------------------------------------------------------------------------
5.1 Function name: ProcessStuffingWorkaround
Purpose:
Input:
Output:
------------------------------------------------------------------------------*/
void InitWorkarounds(u32 decMode, workaround_t *pWorkarounds)
{
u32 asicId = DWLReadAsicID();
u32 asicVer = asicId >> 16;
u32 asicBuild = asicId & 0xFFFF;
/* set all workarounds off by default */
pWorkarounds->mpeg.stuffing = HANTRO_FALSE;
pWorkarounds->mpeg.startCode = HANTRO_FALSE;
pWorkarounds->rv.multibuffer = HANTRO_FALSE;
/* 8170 decoder does not support bad stuffing bytes. */
if( asicVer == 0x8170U)
{
if( decMode == 5 || decMode == 6 || decMode == 1)
pWorkarounds->mpeg.stuffing = HANTRO_TRUE;
else if ( decMode == 8)
pWorkarounds->rv.multibuffer = HANTRO_TRUE;
}
else if( asicVer == 0x8190U )
{
switch(decMode)
{
case 1: /* MPEG4 */
if( asicBuild < 0x2570 )
pWorkarounds->mpeg.stuffing = HANTRO_TRUE;
break;
case 2: /* H263 */
/* No HW tag supports this */
pWorkarounds->mpeg.stuffing = HANTRO_TRUE;
break;
case 5: /* MPEG2 */
case 6: /* MPEG1 */
if( asicBuild < 0x2470 )
pWorkarounds->mpeg.stuffing = HANTRO_TRUE;
break;
case 8: /* RV */
pWorkarounds->rv.multibuffer = HANTRO_TRUE;
}
}
else if(asicVer == 0x9170U)
{
if( decMode == 8 && asicBuild < 0x1270 )
pWorkarounds->rv.multibuffer = HANTRO_TRUE;
}
else if(asicVer == 0x9190U)
{
if( decMode == 8 && asicBuild < 0x1460 )
pWorkarounds->rv.multibuffer = HANTRO_TRUE;
}
else if(asicVer == 0x6731U) /* G1 */
{
if( decMode == 8 && asicBuild < 0x1070 )
pWorkarounds->rv.multibuffer = HANTRO_TRUE;
}
if (decMode == 5 /*MPEG2*/ )
pWorkarounds->mpeg.startCode = HANTRO_TRUE;
}
/*------------------------------------------------------------------------------
5.1 Function name: PrepareStartCodeWorkaround
Purpose: Prepare for start code workaround checking; write magic word
to last 8 bytes of the picture (frame or field)
Input:
Output:
------------------------------------------------------------------------------*/
void PrepareStartCodeWorkaround( u8 *pDecOut, u32 vopWidth, u32 vopHeight,
u32 topField )
{
u32 i;
u8 * pBase;
pBase = pDecOut + vopWidth*vopHeight*256 - 8;
if (topField)
pBase -= 16*vopWidth;
for( i = 0 ; i < MAGIC_WORD_LENGTH ; ++i )
pBase[i] = magicWord[i];
}
/*------------------------------------------------------------------------------
5.1 Function name: ProcessStartCodeWorkaround
Purpose: Check bytes written in PrepareStartCodeWorkaround(). If bytes
match magic word, then error happened earlier on in the picture.
If bytes mismatch, then HW got to end of picture and timeout
interrupt is most likely because of corrupted startcode. In
this case we just ignore timeout.
Note: in addition to ignoring timeout, SW needs to find
next start code as HW does not update stream end pointer
properly. Methods of searching next startcode are mode
specific and cannot be done here.
Input:
Output:
HANTRO_TRUE
HANTRO_FALSE
------------------------------------------------------------------------------*/
u32 ProcessStartCodeWorkaround( u8 * pDecOut, u32 vopWidth, u32 vopHeight,
u32 topField )
{
u32 i;
u8 * pBase;
//u32 numMbs;
u32 match = HANTRO_TRUE;
pBase = pDecOut + vopWidth*vopHeight*256 - 8;
if (topField)
pBase -= 16*vopWidth;
for( i = 0 ; i < MAGIC_WORD_LENGTH && match ; ++i )
if( pBase[i] != magicWord[i] )
match = HANTRO_FALSE;
return match ? HANTRO_FALSE : HANTRO_TRUE;
}