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; 
    } 
}