www.pudn.com > Net_apps.rar > HttpStream.c


//************************************************************* 
// Copyright 2003 Service & Quality Technology CO., LTD. 
// ALL RIGHTS RESERVED. 
// This software is provided under license and contains proprietary 
// and confidential material which is the property of SQ tech. 
// 
// FileName     : HttpStream.c 
// Description  : send audio video 
// Reversion    : 0.1 ,Date : 2004/03/18 ,Author  : gofly 
//                Comment : first implementation 
// 
//************************************************************* 
 
#include "opt.h" 
//Panda Add 
//Begin 
//#include "..\drive\fs\md_fs.h" 
//End 
#if HTTP_OPEN 
#include "..\include\L3\net_apps\httpd\api\HttpStream.h" 
 
#include "..\include\L3\net_apps\httpd\html\audio.h" 
#include "..\include\L0\video\detection.h" 
#include "..\include\L2\system\24c08.h" 
#include "..\include\L3\back_image\bgimg.h"    //add by jgy 
#include "..\include\L3\gpio\sd_q.h"    //add by jgy 10/11/05 
 
THttpStreamCtrlBlack  GtHSCB; 
extern OS_EVENT *BackGetImgEvenSem; 
INT8U    M1count=0; /*multione counter for one image by jjl*/ 
JPG_BUF *M1p; 
 
#define FPS_IDLE  3         //add by jgy  8/24/05 when no motion detected, send images of FPS_IDLE per second 
/* 
	0x0a,0x0a,0x2d,0x2d,0x6d,0x79,0x62,0x6f,0x75,0x6e,0x64, 
0x61,0x72,0x79,0x0a, 
*/ 
/* 
char  Video_Jpg_Sample_Head[]={ 
0x2a,0x2a,0x2a,0x2a,   //magic number ****   									  4 bytes 
//0x16,0x00,             // head size = 4+2+4+1+2+2+1+1+1+1+1+2=22=0x16     2 bytes 
0xbc,0x46,0x00,0x00,   // bitstream size		sizeof(jpg)						  4 bytes 
0x02,//320*240         // 0x01 160*120 0x02 320*240 0x04 640*480          1 bytes 
0x46,0x00,             //qtable														  2 bytes 
0xd3,0x07,             // 
0x0a,                  //る 
0x14,                  //ら 
0x01,                  // 
0x02,                  //だ 
0x03,                  // 
0x6b,0x03,             //睝 
 
} ; 
  */ 
//---- 20bytes---// 
char  Video_Jpg_Sample_Head[]= 
{ 
    0x2a,0x2a,              //magic number * 
    0xbc,0x46,0x00,0x00,    // jpg size 
    0x00,0x00,              // jpg width 
    0x00,0x00,              // jpg height 
    0x46,                   // qtable 
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 
}; 
//*********************************************** 
// StreamAdd(void *data) 
// Description  : add socket to GtHSCB(http stream ctrl black) 
//                 and clear socket in HCB(http ctrl black) 
// Parameters   : 
// Returns      : 
//*********************************************** 
INT8U StreamAdd(void *data, INT8U index) 
{ 
    INT8U                         i; 
    static INT16U         pid      =    2000; 
    THttpStreamCtrlBlack *ptHSCB   =   &GtHSCB; 
    THttpCtrlBlack       *ptHCB    =    data ; 
 
    for(i = 0; i < HTTP_MAX_STREAM_IMAGE ; i++) 
    { 
        if(ptHSCB->PID[i] == 0xff) break; 
    } 
 
    if(HTTP_MAX_STREAM_IMAGE == i) 
       return HTTP_R_ERR; 
 
    if(!strncmp("/cgi-bin/Stream?Video", ptHCB->Order[index], 21)) 
    { 
       ptHSCB->AccessTime[i]    =    OSTimeGet(); 
 
       ptHSCB->type[i]          =    HTTP_STREAM_VIDEO; 
       ptHSCB->Sock[i]          =    ptHCB->Sock[index]; 
 
       pid                      =    pid++; 
 
 
       HttpClearHCBByIndex((void*)data, index); 
       ptHSCB->PID[i]           =    pid; 
       ptHSCB->Stat[i]          =    HTTP_STREAM_STAT_NEW; 
       if(pid > 3000) pid = 2000; // pid = 2000 ~ 3000 
 
       return HTTP_R_OK; 
 
 
    } 
    else 
    { 
       return HTTP_R_ERR;   // to bring about sock destory 
    } 
 
 
 
} 
//*********************************************** 
// HttpStream(void *data) 
// Description  : send audio video 
// Parameters   : 
// Returns      : 
//*********************************************** 
 
void HttpStream(void *data) 
{ 
 
    INT8U                   i; 
    INT8U                   count = 0; 
    struct  timeval         timeout={1,0}; 
    fd_set                  writeset; 
    INT8U                   maxfdp1; 
    INT32S                  len; 
    INT32S                  SendLen; 
    THttpStreamCtrlBlack *ptHSCB   =   &GtHSCB; 
    HttpStreamInit((void*)ptHSCB); 
 
 
 
   while(1) 
   { 
        FD_ZERO(&writeset); 
 
        for(i = 0, count = 0; i < HTTP_MAX_STREAM_IMAGE; i++) 
        { 
            if(ptHSCB->PID[i] != 0xff && 
                (ptHSCB->Stat[i] == HTTP_STREAM_STAT_NEW || 
                    ptHSCB->Stat[i] == HTTP_STREAM_STAT_SEN) 
              ) 
            { 
                ptHSCB->Stat[i] = HTTP_STREAM_STAT_SEN; 
 
                FD_SET(ptHSCB->Sock[i], &writeset); 
                count++; 
                if( maxfdp1 <   ptHSCB->Sock[i] + 1) 
                    maxfdp1   =  ptHSCB->Sock[i] + 1; 
            } 
 
 
        } /*for(i = 0, count = 0; i < HTTP_MAX_SOCKET; i++)*/ 
 
        if(count == 0) 
        { 
            OSTimeDlyHMSM(0, 0, 0, 5); 
            continue; 
        } 
 
         select(maxfdp1, 0, &writeset, 0,&timeout); 
 
        for(i = 0; i < HTTP_MAX_STREAM_IMAGE; i++) 
        { 
            if(ptHSCB->Sock[i] == INVALID_SOCKET 
              || ptHSCB->Stat[i] != HTTP_STREAM_STAT_SEN) 
                continue; 
 
            if( FD_ISSET(ptHSCB->Sock[i], &writeset) ) 
            { 
 
 
                GoToSendStream: 
                ptHSCB->AccessTime[i]    = OSTimeGet(); 
                len = 0; 
                if(ptHSCB->File[i] != NULL) 
                { 
 
                    SendLen = ptHSCB->TotalLen[i] - ptHSCB->SendLen[i]; 
        
                   if(count >= 3) 
                  { 
                        SendLen = min(SendLen, 1460); 
                    } 
                    else    if(SendLen >1460) 
                    { 
                        SendLen = min(SendLen , 
                            TCP_SND_BUF-socket_check_sendbuf(ptHSCB->Sock[i])) ; 
                             
                        SendLen = (SendLen/1460)*1460; 
 
 
                    } 
 
                    len = send(ptHSCB->Sock[i] 
                        ,ptHSCB->File[i] + ptHSCB->SendLen[i] 
                        ,SendLen 
                        ,0); 
 
 
 
 
                    //----- gofly debug------- 
 
                  	//ptHSCB->SendLen[i] = 0; 
                 	//while(1){ 
 
                	//printf("%p %d %d \n",ptHSCB->File[i] + ptHSCB->SendLen[i],len); 
 
                    //ptHSCB->SendLen[i] += 1024; 
 
                  	//} 
                    //--------- gofly debug 
 
                  	//if((len % 1460)) 
                    // printf("%d %d %d  %d %d \n",i,len , socket_check_sendbuf(ptHSCB->Sock[i])); 
                
 
                   	/* 
                    len = send(ptHSCB->Sock[i] 
                        ,ptHSCB->File[i] + ptHSCB->SendLen[i] 
                        ,ptHSCB->TotalLen[i] - ptHSCB->SendLen[i] 
                        ,0); 
                   	*/ 
                    ptHSCB->SendLen[i] += len; 
 
                } 
 
                if(len < 0) 
                {   //send destory 
                    HttpCloseStreamConnect((void*)ptHSCB, i); 
                    continue; 
                } 
 
                if(ptHSCB->SendLen[i] == ptHSCB->TotalLen[i]) 
                { 
 
                    if(ptHSCB->File[i] != NULL && ptHSCB->TotalLen1[i] != 0) 
                    { 
                       ptHSCB->File[i]      = ptHSCB->File[i] + ptHSCB->TotalLen[i]; 
                       ptHSCB->TotalLen[i]  = ptHSCB->TotalLen1[i]; 
                       ptHSCB->TotalLen1[i] = 0; 
                       ptHSCB->SendLen[i]   = 0; 
                    } 
                    else 
                    { 
                       //--- free image 
                        if(ptHSCB->File[i] != NULL) 
                        { 
                        #if VIDEO_FREE  
                          video_image_free(&ptHSCB->send_jpg[i]); 
                        #endif 
                        } 
                       //--- get image 
                       HttpGetImage((void*)ptHSCB, i); 
                    } 
 
                } 
 
            } 
            else 
            {    //  check timeout 
                if(OSTimeGet() - ptHSCB->AccessTime[i]   > HTTP_SOCK_IDLE_TIMEOUT) 
                { 
                  HttpCloseStreamConnect((void*)ptHSCB, i); 
                  continue; 
 
                } 
 
            }/*if( FD_ISSET(ptHSCB->Sock[i], &writeset) )*/ 
 
        } 
 
 
   }/*   while(1)*/ 
 
} 
 
 
//*********************************************** 
// HttpStreamInit(void *data) 
// Description  : INIT  GtHSCB 
// Parameters   : 
// Returns      : 
//*********************************************** 
void HttpStreamInit(void *data) 
{ 
    INT8U           i; 
    THttpStreamCtrlBlack *ptHSCB   =   &GtHSCB; 
 
    for(i = 0; i < HTTP_MAX_STREAM_IMAGE; i++) 
    { 
      HttpClearHSCBByIndex((void *)ptHSCB, i); 
 
    } 
 
 
 
} 
 
//*********************************************** 
// HttpClearHSCBByIndex(void *data, INT8U index) 
// Description  : INIT  GtHSCB 
// Parameters   : 
// Returns      : 
//*********************************************** 
void HttpClearHSCBByIndex(void *data, INT8U index) 
{ 
    THttpStreamCtrlBlack *ptHSCB =  (INT8U *)data ; 
 
 
    ptHSCB->Sock[index]                  =   INVALID_SOCKET; 
    ptHSCB->Stat[index]                  =   HTTP_STREAM_STAT_CLO; 
    ptHSCB->type[index]                  =   HTTP_STREAM_NULL; 
    ptHSCB->AccessTime[index]            =   0; 
    ptHSCB->TotalLen[index]              =   0; 
    ptHSCB->TotalLen1[index]             =   0; 
    ptHSCB->SendLen[index]               =   0; 
    ptHSCB->File[index]                  =   NULL; 
    ptHSCB->PID[index]                   =   0xff;     
    ptHSCB->send_jpg[index].jpg_file     =   NULL; 
 
 
 
} 
//*********************************************** 
//void HttpCloseConnect(void *data, INT8U index) 
// Description  :  close http clinet socket 
// Parameters   : 
// Returns      : 
// 
//*********************************************** 
void HttpCloseStreamConnect(void *data, INT8U index) 
{ 
    char Msg[256]; 
    THttpStreamCtrlBlack *ptHSCB    =      data ; 
    sprintf(Msg, "HTTP  HttpCloseStreamConnect PID %d\n", ptHSCB->PID[index]); 
    close(ptHSCB->Sock[index]); 
    SHOW_EX1(HTTP_DEBUG, Msg); 
 
    if(ptHSCB->File[index] != NULL) 
    { 
      video_image_free(&ptHSCB->send_jpg[index]); 
 
    } 
 
    //imgmax[index] = 0; 
     
    //printf("out stream"); 
     
    HttpClearHSCBByIndex((void*)data, index); 
} 
//*********************************************** 
//void HttpGetImage(void *data, INT8U index) 
// Description  :  get image 
// Parameters   : 
// Returns      : 
// 
//*********************************************** 
void HttpGetImage(void *data, INT8U index) 
{ 
    SVideoJpgHead    extra_head; 
    //JPG_BUF          send_jpg; 
    THttpStreamCtrlBlack *ptHSCB    =      data ; 
    INT16U Width  = atoi(IoW(NULL, NULL, IOR, ROOT)); 
    INT16U Height = atoi(IoH(NULL, NULL, IOR, ROOT)); 
    INT16U   Qual  = atoi(IoImgSet("IMG_S_GET_C", NULL, IOR, ROOT)); 
 
 
    //set image information 
    ptHSCB->send_jpg[index].jpg_imag_width    =   Width; 
    ptHSCB->send_jpg[index].jpg_imag_height   =   Height; 
    ptHSCB->send_jpg[index].jpg_qual          =   Qual; 
    ptHSCB->send_jpg[index].jpg_shp_smooth    =   0;      //disable shp & smooth 
    ptHSCB->send_jpg[index].jpg_wait_msec     =   0;      //always wait image get 
 
 
    video_image_get((void*)&ptHSCB->send_jpg[index]); 
 
 
    memcpy((char*)&extra_head, (char*)Video_Jpg_Sample_Head, 20); 
    extra_head.Jpg_Size  =  ptHSCB->send_jpg[index].jpg_size; 
    extra_head.Qtable    =  ptHSCB->send_jpg[index].jpg_qual; 
 
    extra_head.Width    =    ptHSCB->send_jpg[index].jpg_imag_width ; 
    extra_head.Height   =    ptHSCB->send_jpg[index].jpg_imag_height ; 
 
 
 
 
    ptHSCB->File[index]             =   ptHSCB->send_jpg[index].jpg_line; 
    ptHSCB->TotalLen[index]         =   ptHSCB->send_jpg[index].jpg_size + 20; 
    ptHSCB->SendLen[index]          =   0; 
 
    memcpy(ptHSCB->send_jpg[index].jpg_line, &extra_head , 20); 
} 
//*********************************************** 
//void HttpGetImage_20040712(void *data, INT8U index) 
// Description  :  get image 盢 stream 硂task  
//                  httpthread task ず 
// Parameters   : 
// Returns      : 
// 
//*********************************************** 
#if MULTIONE 
void HttpGetImage_MultiOne(THttpCtrlBlack *ptHCB, INT8U index) 
{ 
    int i,j=0; 
    INT8U *img_resP,*img_resN; 
    for (i=0;i j 
    } 
    
     
    if (!M1count)       //if Micount =0 get new image 
    { 
        M1count++; 
        video_image_get((void*)&ptHCB->send_jpg[index]); 
        M1p = &ptHCB->send_jpg[index]; 
    } 
    else if (M1count<=j) //if Micount <=j not greater than connect num use prev image 
    { 
        M1count++; 
        ptHCB->send_jpg[index] = *M1p; 
    } 
    else if (M1count > j) //if greater than connect num free image and get new 
    { 
        M1count=1; 
        video_image_free(M1p); 
        for (i=0;i<8;i++) 
        { 
        ptHCB->send_jpg[i] = *M1p; 
        } 
        video_image_get((void*)&ptHCB->send_jpg[index]); 
        M1p = &ptHCB->send_jpg[index]; 
    } 
    return; 
 
 
//video_image_get(jpeg_inf); 
//return; 
} 
#endif 
 
void HttpGetImage_20040712(void *data, INT8U index) 
{ 
   //Panda Add 
   //Begin 
	// MDSAVEINF iMDSaveInf; 
   //End 
 
    JPG_FILLDATA        *jpg_filldata; 
    JPG_DIS_CHAR        *jpg_dis_char; 
 
    //SVideoJpgHead    extra_head; 
    //JPG_BUF          send_jpg; 
    THttpCtrlBlack *ptHCB    =      data ; 
    //static INT16S imgTime; 
    static INT32U imgTime; 
    static INT8U IgnoreImgCount; 
    u8_t fps; 
 
    //INT16U Width  = atoi(IoW(NULL, NULL, IOR, ROOT)); 
    //INT16U Height = atoi(IoH(NULL, NULL, IOR, ROOT)); 
    //INT16U   Qual  = atoi(IoImgSet("IMG_S_GET_C", NULL, IOR, ROOT)); 
 
 
    //set image information 
    //ptHCB->send_jpg[index].jpg_imag_width    =   Width; 
    //ptHCB->send_jpg[index].jpg_imag_height   =   Height; 
    //ptHCB->send_jpg[index].jpg_qual          =   Qual; 
    //ptHCB->send_jpg[index].jpg_shp_smooth    =   0;      //disable shp & smooth 
    //ptHCB->send_jpg[index].jpg_wait_msec     =   0;      //always wait image get 
 
    #if MULTIONE 
    HttpGetImage_MultiOne(ptHCB,index); 
    #else 
    //video_image_get((void*)&ptHCB->send_jpg[index]); 
    if(video_bkimage_get(ptHCB, index) != 0) 
    { 
        return; 
    } 
    if (Sd_trigger_Hotkey) 
    { 
      Sd_trigger_Hotkey = 0; 
      md_write_data(&ptHCB->send_jpg[index]); 
    } 
    #endif 
    //add by jgy 8/24/05 
    //空闲时帧率控制 
    if(!Ply_flag) 
    {//上传数据时不加帧率控制 
     if((eprom_ptos.eprom_opt_trigger.motin_det1 == TRUE) || (eprom_ptos.eprom_opt_trigger.motin_det2 == TRUE)) 
     { 
         if(detection_ctrl.md_warning_count[0] == 0 && detection_ctrl.md_warning_count[1] == 0) 
         { 
             //if(ptHCB->send_jpg[index].jpg_time.tm_sec == imgTime) 
             if(OSTimeGet() - imgTime <= OS_TICKS_PER_SEC) 
             {//malipulate in a second 
                 IgnoreImgCount++; 
                 switch(ptHCB->send_jpg[index].jpg_imag_width) 
                 { 
                     case 640:              //640 X 480 
                         fps = 10 - 1;      //subtract 1 for network transfer quality, may range from 1(best) to 7(worst) 
                        break; 
                     case 320:              //320 X 240 
                         fps = 25 - 2;      //subtract 1 for network transfer quality, may range from 1(best) to 12(worst) 
                         break; 
                     default:               //160 X 120 
                         fps = 30 - 3;      //subtract 1 for network transfer quality, may range from 1(best) to 15(worst) 
                         break; 
                 } 
                 if(IgnoreImgCount < fps / FPS_IDLE) 
                 { 
                     //video_image_free(&ptHCB->send_jpg[index]); 
                     video_bkimage_free(data, index); 
                     //memset(&ptHCB->send_jpg[index], 0, sizeof(JPG_BUF)); 
                     return; 
                 } 
                 //IgnoreImgCount = 0; 
             } 
         } 
     } 
    } 
    //jgy++ 
 
    //memcpy((char*)&extra_head, (char*)Video_Jpg_Sample_Head, 20); 
    //extra_head.Jpg_Size  =  ptHCB->send_jpg[index].jpg_size; 
    //extra_head.Qtable    =  ptHCB->send_jpg[index].jpg_qual; 
 
    //extra_head.Width    =   ptHCB->send_jpg[index].jpg_imag_width ; 
    //extra_head.Height   =   ptHCB->send_jpg[index].jpg_imag_height; 
 
    jpg_filldata                   =   ptHCB->send_jpg[index].jpg_file->fill_data; 
    jpg_filldata->link_count       =   index; 
 
//add by jgy 10/25/05 
    jpg_dis_char                   =   jpg_filldata->jpg_dis_char; 
    if(Rec_flag) 
    {//正在录制当前影像 
       jpg_dis_char[1].char_len = 4; 
       jpg_dis_char[1].char_line = 1;   //2nd line 
       jpg_dis_char[1].char_mod = 1;   //right 
       jpg_dis_char[1].char_color = 0;  //red 
       sprintf(jpg_dis_char[1].char_word, "REC "); 
    } 
    else if(Ply_flag) 
    { 
       jpg_dis_char[1].char_len = 13; 
       jpg_dis_char[1].char_line = 2; 
       jpg_dis_char[1].char_mod = 1; 
       jpg_dis_char[1].char_color = 2;  //blue 
       sprintf(jpg_dis_char[1].char_word, "UPLOADING... "); 
    } 
//jgy++ 
 
    ptHCB->File[index]             =   ptHCB->send_jpg[index].jpg_line; 
    ptHCB->TotalLen[index]         =   ptHCB->send_jpg[index].jpg_size + 20; 
    ptHCB->SendLen[index]          =   0; 
    ptHCB->FileType[index]         =   FILE_TYPE_STREAM; 
    IgnoreImgCount                 =   0; 
    //imgTime                        =   ptHCB->send_jpg[index].jpg_time.tm_sec;      //add by jgy  8/25/05 
    imgTime                        =   OSTimeGet();                              //modified by jgy  10/6/05 
 
     //Panda Add 
     //Begin 
         //iMDSaveInf.jpeg_inf=&(ptHCB->send_jpg[index]); 
         //md_write_data(&iMDSaveInf); 
     //End 
} 
 
void HttpGetHistImage(void *data, INT8U index) 
{ 
    THttpCtrlBlack *ptHCB = data; 
    SD_RING_ELM sd_jpg_inf; 
    JPG_FILLDATA *jpg_filldata; 
    //static BOOLEAN buf_empty = FALSE; 
 
    if(!hist_video_blk.rdy)       //历史图片还没有准备好 
        return; 
    //if(buf_empty == TRUE) 
    //{ 
    //    buf_empty = FALSE; 
    //    OSSemPost(sd_snd_Sem); 
    //} 
    if(SD_Q_FAIL == sd_Q_GetImage(&sd_jpg_inf)) 
    {//图片发送队列已空,给sd卡任务发信号量 
        hist_video_blk.rdy = 0; 
        OSSemPost(sd_snd_Sem); 
        return; 
    } 
    //if(sd_jpg_inf.lst_img == TRUE) 
    //    buf_empty = TRUE; 
    jpg_filldata                   =   sd_jpg_inf.jpg_file->fill_data; 
    jpg_filldata->link_count       =   index;            //保留作断点续传时用 
 
    ptHCB->File[index]             =   sd_jpg_inf.jpg_line; 
    ptHCB->TotalLen[index]         =   sd_jpg_inf.jpg_size + 20; 
    ptHCB->SendLen[index]          =   0; 
    ptHCB->FileType[index]         =   FILE_TYPE_STREAM; 
} 
 
#endif  /*HTTP_OPEN*/