www.pudn.com > Net_apps.rar > backimage.c
//*************************************************************
// Copyright 2005 Rico Technology Development CO., LTD.
// ALL RIGHTS RESERVED.
// This software is provided under license and contains proprietary
// and confidential material which is the property of RICO tech.
//
// FileName :
// Description : establishing back image stream task
// Reversion : 0.1 ,Date : 2005/08/29 ,Author : jgy
// Comment : first implementation.
//
//*************************************************************
#include "..\include\L0\Video\jpeg.h"
#include "..\include\L3\net_apps\IoEnv.h"
#include "..\include\L3\net_apps\httpd\api\httpstream.h"
#include "..\include\L3\back_image\bgimg.h"
#include "..\include\L3\net_apps\httpd\httpserver.h"
#include "..\include\L3\include\mem.h"
#include "..\include\L3\include\xdos.h"
#include "..\include\L3\net_apps\httpd\html\weilianjie.h"
#define DMACTRL (u16_t)0xB627 //101 101 1 0 00 1 0 0 1 1 1 word transfer
extern char Video_Jpg_Sample_Head[]; //defined in HttpStream.c
BACK_IMG_BUF huge BackImgBuf;
OS_EVENT *imgSyncMbox;
void BackImageStream(void *data)
{
#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr;
#endif
INT8U i, err;
INT16U Width, Height, Qual;
SVideoJpgHead extra_head;
BACK_IMG_BUF *bbuf;
BOOLEAN bImg;
bbuf = &BackImgBuf;
for(i = 0; i < BACK_IMG_BUF_SIZE; i++)
{
bbuf->img[i].ref = 0;
bbuf->img[i].maked = 0;
bbuf->img[i].dbuf = (void *)0;
}
bbuf->index = 1;
bbuf->vindex = 1;
imgSyncMbox = OSMboxCreate((void*)1); //初始邮箱里有邮件
i = 0;
OSTimeDlyHMSM(0, 0, 5, 0); //延迟5秒启动
for(;;)
{
bImg = FALSE;
OS_ENTER_CRITICAL();
if(bbuf->img[bbuf->index].ref == 0)
{
if(bbuf->img[bbuf->index].maked)
{
video_image_free((void *)&bbuf->img[bbuf->index].buffer);
bbuf->img[bbuf->index].maked = 0;
OS_EXIT_CRITICAL();
}
else
{
OS_EXIT_CRITICAL();
}
OSMboxPend(imgSyncMbox, 0, &err);
Width = atoi(IoW(NULL, NULL, IOR, ROOT));
Height = atoi(IoH(NULL, NULL, IOR, ROOT));
Qual = atoi(IoImgSet("IMG_S_GET_C", NULL, IOR, ROOT));
//set image information
bbuf->img[bbuf->index].buffer.jpg_imag_width = Width;
bbuf->img[bbuf->index].buffer.jpg_imag_height = Height;
bbuf->img[bbuf->index].buffer.jpg_qual = Qual;
bbuf->img[bbuf->index].buffer.jpg_shp_smooth = 0; //disable shp & smooth
bbuf->img[bbuf->index].buffer.jpg_wait_msec = 0; //always wait image get
if(!video_image_get((void*)&bbuf->img[bbuf->index].buffer)) //未获取到图片时,让出cpu
{
//OSTimeDlyHMSM(0, 0, 1, 0);
continue;
}
OSMboxPost(imgSyncMbox, (void*)1);
memcpy((char*)&extra_head, (char*)Video_Jpg_Sample_Head, 20);
extra_head.Jpg_Size = bbuf->img[bbuf->index].buffer.jpg_size;
extra_head.Qtable = bbuf->img[bbuf->index].buffer.jpg_qual;
extra_head.Width = bbuf->img[bbuf->index].buffer.jpg_imag_width ;
extra_head.Height = bbuf->img[bbuf->index].buffer.jpg_imag_height;
//jpg_filldata = ptHCB->send_jpg[index].jpg_file->fill_data;
//jpg_filldata->link_count = index; //指明传送此图片的连接通道号
memcpy(bbuf->img[bbuf->index].buffer.jpg_line, &extra_head , 20);
OS_ENTER_CRITICAL();
bbuf->vindex = bbuf->index;
bbuf->img[bbuf->vindex].maked = 1;
//OS_EXIT_CRITICAL();
bbuf->index++;
//i = 0;
//if(bbuf->index >= BACK_IMG_BUF_SIZE) bbuf->index = 0;
if(bbuf->index >= BACK_IMG_BUF_SIZE) bbuf->index = 1; //设置哨兵
OS_EXIT_CRITICAL();
bImg = TRUE;
}
else
{
//OS_EXIT_CRITICAL();
bbuf->index++;
//i++;
//if(bbuf->index >= BACK_IMG_BUF_SIZE) bbuf->index = 0;
if(bbuf->index >= BACK_IMG_BUF_SIZE) bbuf->index = 1; //设置哨兵
OS_EXIT_CRITICAL();
}
if(bImg == TRUE)
{
switch(Width)
{
case 640:
OSTimeDlyHMSM(0, 0, 0, 100); //10 fps
break;
default:
OSTimeDlyHMSM(0, 0, 0, 40); //25 fps
break;
}
//continue;
}
//if(i >= BACK_IMG_BUF_SIZE)
//{
// i = 0;
//OSMboxPend(bbuf->WaitMbox, 0, &err);
// OSTimeDlyHMSM(0, 0, 0, 5); //waiting for buffer release
//}
}
}
INT8S video_bkimage_get(void *data, INT8U index)
{
#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr;
#endif
BACK_IMG_BUF *bbuf;
THttpCtrlBlack *ptHCB;
void *tbuf;
bbuf = &BackImgBuf;
ptHCB = data ;
OS_ENTER_CRITICAL();
if(!(bbuf->img[bbuf->vindex].maked))
{
OS_EXIT_CRITICAL();
return -1;
}
memcpy(&ptHCB->send_jpg[index], &bbuf->img[bbuf->vindex].buffer, sizeof(JPG_BUF));
//video_image_lock(&bbuf->img[bbuf->vindex].buffer);
if(bbuf->img[bbuf->vindex].ref == (INT8U)0)
{
bbuf->img[bbuf->vindex].ref++;
ptHCB->ref[index] = bbuf->vindex;
OS_EXIT_CRITICAL();
//copy the image
tbuf = sd_mem_malloc(ptHCB->send_jpg[index].jpg_size + 20 + 2);
//OSSchedLock(); //禁止调度
//OS_ENTER_CRITICAL();
//DMA_copy(1, segofs_2_linear(tbuf), segofs_2_linear((u8_t huge *)ptHCB->send_jpg[index].jpg_line), \
// ((ptHCB->send_jpg[index].jpg_size + 20)/2 + 1), DMACTRL); //word transfer
//OSSchedUnlock(); //解除
//OS_EXIT_CRITICAL();
memcpy((INT8U*)tbuf, ptHCB->send_jpg[index].jpg_line, ptHCB->send_jpg[index].jpg_size + 20);
bbuf->img[ptHCB->ref[index]].dbuf = tbuf;
ptHCB->send_jpg[index].jpg_line = (JPG_LINE *)tbuf;
ptHCB->send_jpg[index].jpg_file = (JPG_HEAD *)((u8_t huge *)tbuf + 20);
}
else
{
ptHCB->send_jpg[index].jpg_line = (JPG_LINE *)bbuf->img[bbuf->vindex].dbuf;
ptHCB->send_jpg[index].jpg_file = (JPG_HEAD *)((u8_t huge *)bbuf->img[bbuf->vindex].dbuf + 20);
bbuf->img[bbuf->vindex].ref++;
ptHCB->ref[index] = bbuf->vindex;
OS_EXIT_CRITICAL();
}
return 0;
}
INT8S video_bkimage_free(void *data, INT8U index)
{
#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr;
#endif
BACK_IMG_BUF *bbuf;
THttpCtrlBlack *ptHCB;
bbuf = &BackImgBuf;
ptHCB = data;
OS_ENTER_CRITICAL();
if(bbuf->img[ptHCB->ref[index]].ref > 0)
{
bbuf->img[ptHCB->ref[index]].ref--;
if(bbuf->img[ptHCB->ref[index]].ref == 0)
{
//video_image_unlock(&bbuf->img[ptHCB->ref[index]].buffer);
OS_EXIT_CRITICAL();
video_image_free((void *)&bbuf->img[ptHCB->ref[index]].buffer);
if(bbuf->img[ptHCB->ref[index]].dbuf != (void *)0)
{
sd_mem_free((void *)bbuf->img[ptHCB->ref[index]].dbuf); //release the image memory
bbuf->img[ptHCB->ref[index]].dbuf = (void *)0;
}
OS_ENTER_CRITICAL();
bbuf->img[ptHCB->ref[index]].maked = 0;
ptHCB->ref[index] = 0;
OS_EXIT_CRITICAL();
}
else
{
ptHCB->ref[index] = 0;
OS_EXIT_CRITICAL();
}
return 0;
}
OS_EXIT_CRITICAL();
return -1;
}
void DMA_copy(INT8U channel, INT32U DestAddr, INT32U SourAddr, INT16U count, INT16U ctrl)
{
outport(0xFFD2, ((SourAddr & 0xFFFF0000)>>16));
outport(0xFFD0, (SourAddr & 0xFFFF));
outport(0xFFD6, (DestAddr & 0xFFFF0000)>>16);
outport(0xFFD4, (DestAddr & 0xFFFF));
outport(0xFFD8, count);
outport(0xFFDA, ctrl);
while(inport(0xFFD8));
}
INT8S sd_mdimage_pool_inpouring(void huge * immit_addr/*存入地址*/, u32_t *size/*缓冲区已占用大小*/, u32_t bufSize/*缓冲区大小*/)
{
#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr;
#endif
BACK_IMG_BUF *bbuf;
void *tbuf;
INT16U sd_ref;
JPG_BUF jpg_inf;
static INT8U Flag = 0;
static u16_t img_width;
if(Flag == 0)
{
Flag = 1;
switch(eprom_ptos.eprom_opt_img.img_size)
{
case 0: img_width = 640; break;
case 1: img_width = 320; break;
case 2: img_width = 160; break;
default: break;
}
}
//if(!immit_addr) return -1;
if(!immit_addr) return 0;
bbuf = &BackImgBuf;
OS_ENTER_CRITICAL();
if(!(bbuf->img[bbuf->vindex].maked))
{
OS_EXIT_CRITICAL();
return 0; //还没有生成图片,正常返回
}
memcpy(&jpg_inf, &bbuf->img[bbuf->vindex].buffer, sizeof(JPG_BUF));
//bbuf->img[bbuf->vindex].ref++;
//sd_ref = bbuf->vindex;
OS_EXIT_CRITICAL();
if(img_width != jpg_inf.jpg_imag_width)
{//分辨率改变,终止本次录制
img_width = jpg_inf.jpg_imag_width;
return 1;
}
//copy the image
if(*size + (jpg_inf.jpg_size + 20 + 2) <= bufSize)
{
//OS_EXIT_CRITICAL();
//OSSchedLock(); //禁止调度
OS_ENTER_CRITICAL();
DMA_copy(1, segofs_2_linear(immit_addr), segofs_2_linear((u8_t huge *)jpg_inf.jpg_line), \
((jpg_inf.jpg_size + 20)/2 + 1), DMACTRL); //word transfer
OS_EXIT_CRITICAL();
//OSSchedUnlock(); //解除
if(jpg_inf.jpg_size & (INT32U)1)
{//奇数图片大小
((u8_t huge *)immit_addr)[jpg_inf.jpg_size + 20] = 0xF0;
*size += jpg_inf.jpg_size + 20 + 1;
}
else
{//偶数图片大小
*(u16_t *)(((u8_t huge *)immit_addr)+jpg_inf.jpg_size + 20) = 0xF0F0; //避免找到错误的"2A 2A"字串而且也不会破坏原图片数据^.^
*size += jpg_inf.jpg_size + 20 + 2;
}
return 0;
}
else
{//sd卡缓冲区已满,立即写入sd卡
return -1;
}
}