483 lines
13 KiB
C
483 lines
13 KiB
C
|
|
#include <stdio.h>
|
|||
|
|
#include <string.h>
|
|||
|
|
#include "osal_file.h"
|
|||
|
|
#include "avidemux.h"
|
|||
|
|
#include "osal/string.h"
|
|||
|
|
|
|||
|
|
#define FourCC(aa, bb, cc, dd) ( ((aa)&0xFF) | (((bb)<<8)&0xFF00) | (((cc)<<16)&0xFF0000) | (((dd)<<24)&0xFF000000) )
|
|||
|
|
#define FourCCCC(i) (i)&0xFF,(i>>8)&0xFF,(i>>16)&0xFF,(i>>24)&0xFF
|
|||
|
|
|
|||
|
|
#ifndef BIT
|
|||
|
|
#define BIT(b) (1<<(b))
|
|||
|
|
#endif
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
// 在parse階段,哪些LIST是需要深入分析的
|
|||
|
|
static int need_parse_list(uint32_t fourcc)
|
|||
|
|
{
|
|||
|
|
return
|
|||
|
|
fourcc == FourCC('A','V','I',' ') ||
|
|||
|
|
fourcc == FourCC('h','d','r','l') ||
|
|||
|
|
fourcc == FourCC('s','t','r','l') ||
|
|||
|
|
0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
#define MAX_LIST_DEPTH 5
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
//avi数据头解析,不是全局变量
|
|||
|
|
void *avidemux_parse(void *fp,void *aviinfo_point)
|
|||
|
|
{
|
|||
|
|
AVISTREAMHEADER strh;
|
|||
|
|
struct _aviindex_chunk indx;
|
|||
|
|
struct avistrinfo *str = NULL;
|
|||
|
|
struct aviinfo *aviinfo = (struct aviinfo *)aviinfo_point;
|
|||
|
|
uint32_t list_end[MAX_LIST_DEPTH]; // RIFF/LIST棧,記錄其結束地址
|
|||
|
|
uint32_t lvl;
|
|||
|
|
uint32_t fcc_size[3]; // 緩存讀入的FourCC及其size
|
|||
|
|
uint32_t pos;
|
|||
|
|
uint32_t err;
|
|||
|
|
memset(aviinfo_point,0,sizeof(struct aviinfo));
|
|||
|
|
lvl = 0;
|
|||
|
|
list_end[lvl] = osal_fsize (fp);
|
|||
|
|
_os_printf ("%s : file size %08X\n", __func__, list_end[lvl]);
|
|||
|
|
uint32_t msk = 0;
|
|||
|
|
pos = 0;
|
|||
|
|
while (pos < list_end[lvl]) {
|
|||
|
|
|
|||
|
|
if (osal_fread ((char*)fcc_size, 1, 8, fp) < 8) {
|
|||
|
|
_os_printf ("%s : read fourcc & size error\n", __func__);
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
// _os_printf ("%s : %c%c%c%c %08X", __func__, FourCCCC(fcc_size[0]), fcc_size[1]);
|
|||
|
|
pos += 8;
|
|||
|
|
// 檢查長度
|
|||
|
|
if (fcc_size[1] + pos > list_end[lvl]) {
|
|||
|
|
_os_printf ("%s : fourcc length error\n", __func__);
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
err = 0;
|
|||
|
|
switch (fcc_size[0]) {
|
|||
|
|
case FourCC('R','I','F','F'):
|
|||
|
|
case FourCC('L','I','S','T'):
|
|||
|
|
// 檢查LIST的類型
|
|||
|
|
if (osal_fread((char*)&fcc_size[2], 1, 4, fp) < 4) {
|
|||
|
|
_os_printf ("%s : read LIST name error\n", __func__);
|
|||
|
|
err = 1;
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
if (need_parse_list(fcc_size[2]) && lvl < MAX_LIST_DEPTH-1) {
|
|||
|
|
// 需要分析這個LIST,並且棧空間還夠用
|
|||
|
|
list_end[++lvl] = pos + fcc_size[1];
|
|||
|
|
pos += 4;
|
|||
|
|
// _os_printf ("%s : pos %08X %08X %08X", __func__, pos, list_end[lvl], fcc_size[1]);
|
|||
|
|
} else {
|
|||
|
|
pos += fcc_size[1];
|
|||
|
|
osal_fseek (fp, pos);
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
case FourCC('s','t','r','h'):
|
|||
|
|
if (osal_fread(((void*)&strh)+2*sizeof(DWORD), 1, sizeof(strh)-2*sizeof(DWORD), fp) < sizeof(strh)-2*sizeof(DWORD)) {
|
|||
|
|
_os_printf ("%s : read strh type error\n", __func__);
|
|||
|
|
err = 1;
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
pos += fcc_size[1];
|
|||
|
|
// _os_printf ("found strh %s %dx%d %d frames", &strh.fccType, strh.rcFrame.right, strh.rcFrame.bottom, strh.dwLength);
|
|||
|
|
|
|||
|
|
if (strh.fccType == FourCC('v','i','d','s')) {
|
|||
|
|
str = &aviinfo->str[0];
|
|||
|
|
str->type = 0;
|
|||
|
|
aviinfo->strmsk |= BIT(0);
|
|||
|
|
msk |= BIT(0);
|
|||
|
|
} else {
|
|||
|
|
str = &aviinfo->str[1];
|
|||
|
|
str->type = 1;
|
|||
|
|
aviinfo->strmsk |= BIT(1);
|
|||
|
|
msk |= BIT(1);
|
|||
|
|
}
|
|||
|
|
str->dwScale = strh.dwScale * 1000;
|
|||
|
|
str->dwRate = strh.dwRate;
|
|||
|
|
str->dwTotalFrames = strh.dwLength;
|
|||
|
|
str->cur = 0;
|
|||
|
|
str->avi = aviinfo;
|
|||
|
|
break;
|
|||
|
|
case FourCC('i','n','d','x'):
|
|||
|
|
if (NULL == str) {
|
|||
|
|
_os_printf ("%s : indx but no strh\n", __func__);
|
|||
|
|
err = 1;
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
if (osal_fread(((void*)&indx)+2*sizeof(DWORD), 1, sizeof(indx)-2*sizeof(DWORD), fp) < sizeof(indx)-2*sizeof(DWORD)) {
|
|||
|
|
_os_printf ("%s : read indx type error\n", __func__);
|
|||
|
|
err = 1;
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
//找到超级索引的数量,然后保存超级索引表,并且计算序号(用于快速搜索)
|
|||
|
|
str->dwIndexNum = indx.nEntriesInUse;
|
|||
|
|
//一次性申请足够空间,读取超级索引表
|
|||
|
|
str->superindex_cache = (struct _avisuperindex_entry_cache*)malloc(str->dwIndexNum*sizeof(struct _avisuperindex_entry_cache));
|
|||
|
|
|
|||
|
|
if(str->superindex_cache)
|
|||
|
|
{
|
|||
|
|
if(osal_fread((char*)str->superindex_cache, 1, str->dwIndexNum*sizeof(struct _avisuperindex_entry_cache), fp) < str->dwIndexNum*sizeof(struct _avisuperindex_entry_cache))
|
|||
|
|
{
|
|||
|
|
_os_printf ("%s : read indx type error\n", __func__);
|
|||
|
|
err = 1;
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
//扫描超级索引,记录索引序号起始
|
|||
|
|
uint32_t offset = 0;
|
|||
|
|
uint32_t max_size = 0;
|
|||
|
|
uint32_t count = 0;
|
|||
|
|
for(int i=0;i<str->dwIndexNum;i++)
|
|||
|
|
{
|
|||
|
|
str->superindex_cache[i].offset = offset;
|
|||
|
|
count = ((str->superindex_cache[i].dwSize - sizeof(struct _aviindex_chunk))/sizeof(struct _avistdindex_entry));
|
|||
|
|
str->superindex_cache[i].dwSize = count;
|
|||
|
|
|
|||
|
|
offset+= count;
|
|||
|
|
if(count > max_size)
|
|||
|
|
{
|
|||
|
|
max_size = count;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//_os_printf("offset:%d\t%X\n",str->superindex_cache[i].offset,str->superindex_cache[i].dwOffsetl);
|
|||
|
|
}
|
|||
|
|
//如果是音频,则帧数修改一下
|
|||
|
|
if(str->type == 1)
|
|||
|
|
{
|
|||
|
|
str->dwTotalFrames = offset;
|
|||
|
|
}
|
|||
|
|
//读取完毕后,去扫描索引最大值,申请最大空间,一次读取一个超级索引
|
|||
|
|
|
|||
|
|
str->stindex_cache = (struct _avistdindex_entry*)malloc(max_size*sizeof(struct _avistdindex_entry));
|
|||
|
|
if(!str->stindex_cache)
|
|||
|
|
{
|
|||
|
|
err = 1;
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
str->dwIndexBase = pos + sizeof(indx)-2*sizeof(DWORD);
|
|||
|
|
//str->dwDuration = str->indx[0].dwDuration;
|
|||
|
|
str->cached_indx_base = 0;
|
|||
|
|
str->cached_ixnn_base = 0;
|
|||
|
|
str->super_idx = ~0;
|
|||
|
|
str->cur = 0;
|
|||
|
|
|
|||
|
|
// _os_printf ("found indx @%08X", str->dwIndexBase);
|
|||
|
|
pos += fcc_size[1];
|
|||
|
|
// 雖然緩存了512B的超級索引,但該長度不是最終的長度
|
|||
|
|
osal_fseek (fp, pos);
|
|||
|
|
break;
|
|||
|
|
default:
|
|||
|
|
pos += fcc_size[1];
|
|||
|
|
osal_fseek (fp, pos);
|
|||
|
|
} // switch (fcc_size[0])
|
|||
|
|
if (err) break;
|
|||
|
|
|
|||
|
|
if (pos == list_end[lvl]) {
|
|||
|
|
// pop
|
|||
|
|
--lvl;
|
|||
|
|
}
|
|||
|
|
if (pos > list_end[lvl]) {
|
|||
|
|
_os_printf ("%s : list overread\n", __func__);
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
} // while (pos < list_end[lvl])
|
|||
|
|
_os_printf ("str[0] : %d @%08X:%08X\n", (int)aviinfo->str[0].dwTotalFrames, (int)aviinfo->str[0].dwIndexBase, (int)aviinfo->str[0].dwIndexNum);
|
|||
|
|
_os_printf ("str[1] : %d @%08X:%08X\n", (int)aviinfo->str[1].dwTotalFrames, (int)aviinfo->str[1].dwIndexBase, (int)aviinfo->str[1].dwIndexNum);
|
|||
|
|
aviinfo->fp = fp;
|
|||
|
|
if(err)
|
|||
|
|
{
|
|||
|
|
|
|||
|
|
for(int i=0;i<2;i++)
|
|||
|
|
{
|
|||
|
|
if(aviinfo->str[i].superindex_cache)
|
|||
|
|
{
|
|||
|
|
free(aviinfo->str[i].superindex_cache);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if(aviinfo->str[i].stindex_cache)
|
|||
|
|
{
|
|||
|
|
free(aviinfo->str[i].stindex_cache);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return NULL;
|
|||
|
|
}
|
|||
|
|
return aviinfo;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
uint32_t get_avidemux_parse_stream(char *path,struct avi_msg *msg)
|
|||
|
|
{
|
|||
|
|
_os_printf("my path:%s\n",path);
|
|||
|
|
void *fp = osal_fopen(path,"rb");
|
|||
|
|
if(!fp)
|
|||
|
|
{
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
memset(msg,0,sizeof(struct avi_msg));
|
|||
|
|
AVISTREAMHEADER strh;
|
|||
|
|
//DWORD fccType;
|
|||
|
|
uint32_t list_end[MAX_LIST_DEPTH]; // RIFF/LIST棧,記錄其結束地址
|
|||
|
|
uint32_t lvl;
|
|||
|
|
uint32_t fcc_size[3]; // 緩存讀入的FourCC及其size
|
|||
|
|
uint32_t pos;
|
|||
|
|
uint32_t err;
|
|||
|
|
uint32_t msk = 0;
|
|||
|
|
lvl = 0;
|
|||
|
|
list_end[lvl] = osal_fsize (fp);
|
|||
|
|
|
|||
|
|
|
|||
|
|
pos = 0;
|
|||
|
|
while (pos < list_end[lvl])
|
|||
|
|
{
|
|||
|
|
if (osal_fread ((char*)fcc_size, 1, 8, fp) < 8) {
|
|||
|
|
_os_printf ("%s : read fourcc & size error\n", __func__);
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
pos += 8;
|
|||
|
|
// 檢查長度
|
|||
|
|
if (fcc_size[1] + pos > list_end[lvl]) {
|
|||
|
|
_os_printf ("%s : fourcc length error\n", __func__);
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
err = 0;
|
|||
|
|
switch (fcc_size[0])
|
|||
|
|
{
|
|||
|
|
case FourCC('R','I','F','F'):
|
|||
|
|
case FourCC('L','I','S','T'):
|
|||
|
|
// 檢查LIST的類型
|
|||
|
|
if (osal_fread((char*)&fcc_size[2], 1, 4, fp) < 4) {
|
|||
|
|
_os_printf ("%s : read LIST name error\n", __func__);
|
|||
|
|
err = 1;
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
if (need_parse_list(fcc_size[2]) && lvl < MAX_LIST_DEPTH-1) {
|
|||
|
|
// 需要分析這個LIST,並且棧空間還夠用
|
|||
|
|
list_end[++lvl] = pos + fcc_size[1];
|
|||
|
|
pos += 4;
|
|||
|
|
} else {
|
|||
|
|
pos += fcc_size[1];
|
|||
|
|
osal_fseek (fp, pos);
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
case FourCC('s','t','r','h'):
|
|||
|
|
if (osal_fread((void*)&strh.fccType, 1, sizeof(strh)-2*sizeof(DWORD), fp) < sizeof(strh)-2*sizeof(DWORD)) {
|
|||
|
|
_os_printf ("%s : read strh type error\n", __func__);
|
|||
|
|
err = 1;
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
pos += fcc_size[1];
|
|||
|
|
if (strh.fccType == FourCC('v','i','d','s')) {
|
|||
|
|
msk |= BIT(0);
|
|||
|
|
msg->video_sample_rate = strh.dwRate;
|
|||
|
|
} else {
|
|||
|
|
msk |= BIT(1);
|
|||
|
|
msg->audio_sample_rate = strh.dwRate/strh.dwSampleSize;
|
|||
|
|
}
|
|||
|
|
osal_fseek (fp, pos);
|
|||
|
|
break;
|
|||
|
|
default:
|
|||
|
|
pos += fcc_size[1];
|
|||
|
|
osal_fseek (fp, pos);
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
if (pos == list_end[lvl])
|
|||
|
|
{
|
|||
|
|
--lvl;
|
|||
|
|
}
|
|||
|
|
if (pos > list_end[lvl]) {
|
|||
|
|
_os_printf ("%s : list overread\n", __func__);
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
_os_printf("end pos:%X\t%X\t%X\n",pos,list_end[lvl],msk);
|
|||
|
|
if(fp)
|
|||
|
|
{
|
|||
|
|
osal_fclose(fp);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return msk;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
//主要是偏移到cur的对应位置,并且返回对应数据的位置以及size,返回一个错误
|
|||
|
|
uint32_t read_avi_offset(struct avistrinfo *str,uint32_t *base,uint32_t *size)
|
|||
|
|
{
|
|||
|
|
uint32_t err = 0;
|
|||
|
|
*base = 0;
|
|||
|
|
*size = 0;
|
|||
|
|
uint8_t st_index_read = 0;
|
|||
|
|
if(str->cur >= str->dwTotalFrames)
|
|||
|
|
{
|
|||
|
|
err = 1;
|
|||
|
|
goto read_avi_offset_end;
|
|||
|
|
}
|
|||
|
|
//如果超级索引序号比最大的索引大,可能是第一次读取
|
|||
|
|
if(str->super_idx >= str->dwIndexNum)
|
|||
|
|
{
|
|||
|
|
err = 2;
|
|||
|
|
//那么计算cur当前的位置
|
|||
|
|
for(int i=0;i<str->super_idx;i++)
|
|||
|
|
{
|
|||
|
|
if(str->superindex_cache[i].offset+str->superindex_cache[i].dwSize > str->cur && str->superindex_cache[i].offset <= str->cur)
|
|||
|
|
{
|
|||
|
|
str->super_idx = i;
|
|||
|
|
st_index_read = 1;
|
|||
|
|
err = 0;
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
err = 3;
|
|||
|
|
//如果在范围,则不需要处理
|
|||
|
|
if(str->superindex_cache[str->super_idx].offset+str->superindex_cache[str->super_idx].dwSize > str->cur && str->superindex_cache[str->super_idx].offset <= str->cur)
|
|||
|
|
{
|
|||
|
|
err = 0;
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
//现在超级索引得到的偏移比cur大,那么就要从0开始搜索
|
|||
|
|
if(str->superindex_cache[str->super_idx].offset > str->cur)
|
|||
|
|
{
|
|||
|
|
for(int i=0;i<str->dwIndexNum;i++)
|
|||
|
|
{
|
|||
|
|
if(str->superindex_cache[i].offset+str->superindex_cache[i].dwSize > str->cur && str->superindex_cache[i].offset <= str->cur)
|
|||
|
|
{
|
|||
|
|
str->super_idx = i;
|
|||
|
|
st_index_read = 1;
|
|||
|
|
err = 0;
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
//从当前位置开始搜索
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
for(int i=str->super_idx;i<str->dwIndexNum;i++)
|
|||
|
|
{
|
|||
|
|
if(str->superindex_cache[i].offset+str->superindex_cache[i].dwSize > str->cur && str->superindex_cache[i].offset <= str->cur)
|
|||
|
|
{
|
|||
|
|
str->super_idx = i;
|
|||
|
|
st_index_read = 1;
|
|||
|
|
err = 0;
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
if(err)
|
|||
|
|
{
|
|||
|
|
_os_printf("err:%d\n",err);
|
|||
|
|
goto read_avi_offset_end;
|
|||
|
|
}
|
|||
|
|
//已经找到对应的索引号,那就判断是否需要读取标准索引区
|
|||
|
|
if(!err && st_index_read)
|
|||
|
|
{
|
|||
|
|
//读取标准索引区
|
|||
|
|
osal_fseek (str->avi->fp, str->superindex_cache[str->super_idx].dwOffsetl);
|
|||
|
|
osal_fread((char*)&str->chunk,1,sizeof(struct _aviindex_chunk),str->avi->fp);
|
|||
|
|
osal_fread ((char*)str->stindex_cache, 1, str->superindex_cache[str->super_idx].dwSize*sizeof(struct _avistdindex_entry), str->avi->fp);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//读取完标准索引,就返回base、size
|
|||
|
|
uint32_t offset = str->cur - str->superindex_cache[str->super_idx].offset;
|
|||
|
|
*base = str->stindex_cache[offset].dwOffset+str->chunk.dwBaseOffsetl;
|
|||
|
|
*size = str->stindex_cache[offset].dwSize;
|
|||
|
|
//偏移位置
|
|||
|
|
osal_fseek (str->avi->fp, *base);
|
|||
|
|
|
|||
|
|
|
|||
|
|
str->cur ++;
|
|||
|
|
read_avi_offset_end:
|
|||
|
|
|
|||
|
|
return err;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
//从当前位置去读取数据内容,buf是4 byte对齐
|
|||
|
|
uint32_t read_avi_data(struct avistrinfo *str,char *buf,uint32_t size)
|
|||
|
|
{
|
|||
|
|
uint32_t read_len = 0;
|
|||
|
|
read_len = osal_fread(buf,1,size,str->avi->fp);
|
|||
|
|
return read_len;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void free_aviinfo_point(struct aviinfo *info)
|
|||
|
|
{
|
|||
|
|
for(int i=0;i<2;i++)
|
|||
|
|
{
|
|||
|
|
if(info->str[i].superindex_cache)
|
|||
|
|
{
|
|||
|
|
free(info->str[i].superindex_cache);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if(info->str[i].stindex_cache)
|
|||
|
|
{
|
|||
|
|
free(info->str[i].stindex_cache);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void set_avi_cur(struct avistrinfo *info,int cur)
|
|||
|
|
{
|
|||
|
|
info->cur = cur;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
uint32_t get_avi_cur(struct avistrinfo *info)
|
|||
|
|
{
|
|||
|
|
return info->cur;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
#if 0
|
|||
|
|
uint32_t test_space[100*1024];
|
|||
|
|
void play_avi_file(void *aviinfo_point)
|
|||
|
|
{
|
|||
|
|
uint32_t base,size;
|
|||
|
|
uint32_t base_tmp = 0;
|
|||
|
|
char *buf = (char*)test_space;
|
|||
|
|
struct aviinfo *info = (struct aviinfo *)aviinfo_point;
|
|||
|
|
_os_printf("%s:%d\n",__FUNCTION__,__LINE__);
|
|||
|
|
int count = 0;
|
|||
|
|
int count_tmp = 0;
|
|||
|
|
while(1)
|
|||
|
|
{
|
|||
|
|
read_avi_offset(&info->str[0],&base,&size);
|
|||
|
|
_os_printf("base:%X\tsize:%d\tcount:%d\n",base,size,count++);
|
|||
|
|
if(base == 0)
|
|||
|
|
{
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if(base_tmp != base)
|
|||
|
|
{
|
|||
|
|
base_tmp = base;
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
count_tmp++;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
_os_printf("count_tmp:%d\n",count_tmp);
|
|||
|
|
}
|
|||
|
|
#endif
|