📄 gif_decoder_v2.c
字号:
/*****************************************************************************
* Copyright Statement:
* --------------------
* This software is protected by Copyright and the information contained
* herein is confidential. The software may not be copied and the information
* contained herein may not be used or disclosed except with the written
* permission of MediaTek Inc. (C) 2005
*
* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
*
* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
*
* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
*
*****************************************************************************/
/*******************************************************************************
* Filename:
* ---------
* gif_decoder_v2.c
*
* Project:
* --------
* MAUI
*
* Description:
* ------------
* The drive of gif decoder version 2
* (supported on MT6228 and later version chips)8
*
* Author:
* -------
* -------
*
*==============================================================================
* HISTORY
* Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
*------------------------------------------------------------------------------
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
*------------------------------------------------------------------------------
* Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
*==============================================================================
*******************************************************************************/
// include header files
#include "kal_release.h"
#include "reg_base.h"
#include "intrCtrl.h"
#include "drv_comm.h"
#include "gpt_sw.h"
#include "visual_comm.h"
#include "drm_gprot.h"
#include "fat_fs.h"
#include "gif_decoder_v2.h"
#include "bytestream_hw.h"
#include "2d_engine.h"
#include "visualhisr.h"
#if defined(USE_HW_GIF_DECODER_V2)
gif_dcb_struct gif_dcb;
gif_state_enum gif_state;
VISUAL_HISR_ID gif_hisr; // hisr
kal_uint8 gif_gpt_handle; // handler of gpt timer
gif_cache_struct gif_cache[GIF_CACHE_NUM];
kal_uint32 gif_cache_counter; // current cache counter
kal_uint32 gif_cache_hit_count; // accumulate the hit count
kal_uint8 gif_cache_index;
gif_disposal_enum gif_last_disposal_method,gif_cur_disposal_method;
/*************************************************************************
* FUNCTION
* gif_get_cache
*
* DESCRIPTION
* 1. serarch the cache to check if the id is in cache, otherwise , find the
* oldest one and replace it.
* 2. the found cache index is store in the gif_cache_index
*
* PARAMETERS
* id: cache id to distinguish differnt gif images.
* ptr: cache address
*
* RETURNS
* KAL_TRUE: the id is in cache
* KAL_FALSE: the id is not in cache
*
* GLOBALS AFFECTED
* gif_dcb
*************************************************************************/
kal_bool gif_get_cache(kal_uint32 id, gif_cache_struct** ptr, kal_bool update)
{
kal_uint32 i;
kal_uint32 index;
// search if the id is in the cache, start from the latest one
i = 0;
do{
index = GIF_CACHE_GET_INDEX(gif_cache_counter-i++);
if(id == gif_cache[index].id )
{
gif_cache_hit_count++;
gif_cache_index = index;
*ptr = &gif_cache[index];
return KAL_TRUE;
}
}while(i<GIF_CACHE_NUM);
// not in cache and replace the oldest one
if (update)
{
gif_cache_counter++;
index = GIF_CACHE_GET_INDEX(gif_cache_counter-GIF_CACHE_NUM);
*ptr = &gif_cache[index];
gif_cache[index].valid_fn = 0;
gif_cache[index].total_fn = 0xffff;
gif_cache[index].latest_fn[0].fn = 0;
gif_cache[index].latest_fn[1].fn = 0;
gif_cache[index].id = id;
gif_cache_index = index;
}
return KAL_FALSE;
}
/*************************************************************************
* FUNCTION
* gif_reset_cache
*
* DESCRIPTION
* reset the id of the cache
*
* PARAMETERS
*
* RETURNS
*
* GLOBALS AFFECTED
*************************************************************************/
void gif_reset_cache(void)
{
kal_uint32 i;
for(i=0;i<GIF_CACHE_NUM;i++)
{
gif_cache[i].id = 0;
}
}
/*************************************************************************
* FUNCTION
* gif_reset_cache_entry
*
* DESCRIPTION
* reset the id of the cache
*
* PARAMETERS
*
* RETURNS
*
* GLOBALS AFFECTED
*************************************************************************/
void gif_reset_cache_entry(kal_uint32 id)
{
kal_uint32 i;
for(i=0;i<GIF_CACHE_NUM;i++)
{
if(gif_cache[i].id==id)
gif_cache[i].id = 0;
}
}
/*************************************************************************
* FUNCTION
* gif_update_cache_offset
*
* DESCRIPTION
* 1. decode one following frame
* 2. using polling instead interrupt event
*
* PARAMETERS
*
* RETURNS
* KAL_TRUE : a frame has been decoded
* KAL_FALSE: decode fail
*
* GLOBALS AFFECTED
* gif_dcb
*************************************************************************/
INTERNAL_FUNC void gif_update_cache_offset( kal_uint16 fn, kal_uint32 offset,gif_disposal_enum last_disposal)
{
gif_cache_struct *cache = &gif_cache[gif_cache_index];
if( fn > cache->valid_fn)
{
if(fn < GIF_CACHE_FRAME_NUM)
{
cache->valid_fn = fn;
cache->frame_offset[fn] = offset;
cache->last_disposal[fn] = last_disposal;
}
else
{
if(cache->latest_fn[0].fn==0 || cache->latest_fn[1].fn==0)
{
cache->latest_fn[0].fn = fn;
cache->latest_fn[0].offset =offset;
cache->latest_fn[0].last_disposal=last_disposal;
cache->latest_fn[1].fn = fn;
cache->latest_fn[1].offset =offset;
cache->latest_fn[1].last_disposal=last_disposal;
}
else if(fn < cache->latest_fn[0].fn)
{
cache->latest_fn[1].fn = cache->latest_fn[0].fn;
cache->latest_fn[1].offset = cache->latest_fn[0].offset;
cache->latest_fn[1].last_disposal=cache->latest_fn[0].last_disposal;
cache->latest_fn[0].fn = fn;
cache->latest_fn[0].offset =offset;
cache->latest_fn[0].last_disposal=last_disposal;
}
else if(fn > cache->latest_fn[0].fn && fn < cache->latest_fn[1].fn)
{
cache->latest_fn[1].fn = fn;
cache->latest_fn[1].offset = offset;
cache->latest_fn[1].last_disposal=last_disposal;
}
else if (fn > cache->latest_fn[1].fn)
{
cache->latest_fn[0].fn = cache->latest_fn[1].fn;
cache->latest_fn[0].offset = cache->latest_fn[1].offset;
cache->latest_fn[0].last_disposal=cache->latest_fn[1].last_disposal;
cache->latest_fn[1].fn = fn;
cache->latest_fn[1].offset =offset;
cache->latest_fn[1].last_disposal=last_disposal;
}
}
}
}
/*************************************************************************
* FUNCTION
* gif_get_cache_offset
*
* DESCRIPTION
* 1. decode one following frame
* 2. using polling instead interrupt event
*
* PARAMETERS
*
* RETURNS
* KAL_TRUE : a frame has been decoded
* KAL_FALSE: decode fail
*
* GLOBALS AFFECTED
* gif_dcb
*************************************************************************/
INTERNAL_FUNC void gif_get_cache_offset( kal_uint16 fn, kal_uint32* offset)
{
gif_cache_struct *cache = &gif_cache[gif_cache_index];
if(fn > cache->valid_fn)
{
if(cache->latest_fn[0].fn != 0 && cache->latest_fn[1].fn != 0)
{
if(fn >= cache->latest_fn[0].fn && fn < cache->latest_fn[1].fn)
{
gif_dcb.cur_fn = cache->latest_fn[0].fn;
*offset = cache->latest_fn[0].offset;
}
else if(fn >= cache->latest_fn[1].fn)
{
gif_dcb.cur_fn = cache->latest_fn[1].fn;
*offset = cache->latest_fn[1].offset;
}
else
{
gif_dcb.cur_fn = cache->valid_fn;
*offset = cache->frame_offset[cache->valid_fn];
}
}
else
{
gif_dcb.cur_fn = cache->valid_fn;
*offset = cache->frame_offset[cache->valid_fn];
}
}
else
{
gif_dcb.cur_fn = fn;
*offset = cache->frame_offset[fn];
}
}
INTERNAL_FUNC void gif_get_last_disposal( kal_uint16 fn, gif_disposal_enum* last_disposal)
{
gif_cache_struct *cache = &gif_cache[gif_cache_index];
*last_disposal = GIF_NO_ACTION;
if(fn > cache->valid_fn)
{
if(cache->latest_fn[0].fn == fn)
*last_disposal = cache->latest_fn[0].last_disposal;
else if(cache->latest_fn[1].fn == fn)
*last_disposal = cache->latest_fn[1].last_disposal;
}
else
{
*last_disposal = cache->last_disposal[fn];
}
}
INTERNAL_FUNC void gif_lisr_entry(void)
{
IRQMask(IRQ_GIF_CODE);
//kal_activate_hisr(gif_hisr);
visual_active_hisr(VISUAL_GIF_HISR_ID);
}
INTERNAL_FUNC void gif_hisr_entry(void)
{
kal_uint32 boundary,offset,flush_dist;
GIF_STOP_TIMER();
gif_dcb.int_status = DRV_Reg(GIF_IRQ_STATUS);
if(gif_dcb.int_status == GIF_STATUS_COMPLETE)
{
hw_bytestream_dcb_struct *bytestream;
boundary = DRV_Reg32(GIF_FILE_BOUNDARY);
flush_dist=boundary-gif_dcb.lzw_start;
GIF_TELL(&bytestream);
if(bytestream->t == HW_BYTESTREAM_TYPE_FILE &&
bytestream->type.file.buffer_content_size<flush_dist) //hw over read
gif_dcb.int_status=GIF_STATUS_PIXELERR;
}
gif_dcb.gif_cb(gif_dcb.int_status, gif_dcb.cur_fn);
if(gif_dcb.int_status == GIF_STATUS_COMPLETE)
{
GIF_FLUSH(flush_dist);
offset = GIF_TELL(NULL);
gif_dcb.cur_fn++;
gif_update_cache_offset(gif_dcb.cur_fn, offset,gif_cur_disposal_method);
gif_state = GIF_STATE_READY;
GIF_RESET();
}
else if(gif_dcb.int_status == GIF_STATUS_INEMPTY)
{
gif_state = GIF_STATE_PAUSE;
}
else
{
gif_state = GIF_STATE_ERR;
}
DRVPDN_Enable(DRVPDN_CON3,DRVPDN_CON3_GIF,PDN_GIF);
IRQUnmask(IRQ_GIF_CODE);
}
INTERNAL_FUNC void gif_timeout_hander(void* p)
{
gif_state = GIF_STATE_ERR;
gif_dcb.is_timeout = KAL_TRUE;
kal_print("hw gif decode timeout");
DRV_WriteReg32(GIF_IRQ_EN, GIF_IRQ_EN_OFF);
GIF_RESET();
DRVPDN_Enable(DRVPDN_CON3,DRVPDN_CON3_GIF,PDN_GIF);
if(gif_dcb.gif_cb != NULL)
gif_dcb.gif_cb(GIF_STATUS_TIMEOUT, gif_dcb.cur_fn);
}
INTERNAL_FUNC kal_bool gif_g2d_fillbg(void)
{
gif_config_struct *cfg = gif_dcb.cfg;
g2d_rectangle_fill_struct data;
g2d_buffer_struct dest;
kal_uint32 r,g,b;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -