www.pudn.com > Net_apps.rar > HttpStream00.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" 
#if HTTP_OPEN 
#include "..\net\proj\unixsim\net_apps\httpd\api\HttpStream.h" 
THttpStreamCtrlBlack  GtHSCB; 
/* 
	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_SOCKET ; i++) 
    { 
        if(ptHSCB->PID[i] == 0xff) break; 
    } 
 
    if(HTTP_MAX_SOCKET == 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_SOCKET; 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; 
        } 
       
        count =  select(maxfdp1, 0, &writeset, 0,&timeout); 
 
        for(i = 0; i < HTTP_MAX_SOCKET; i++) 
        { 
            if(ptHSCB->Sock[i] == INVALID_SOCKET 
              || ptHSCB->Stat[i] != HTTP_STREAM_STAT_SEN) 
                continue; 
 
            HttpGetImage((void*)ptHSCB, i); 
 
            if( FD_ISSET(ptHSCB->Sock[i], &writeset) ) 
            { 
                ptHSCB->AccessTime[i]    = OSTimeGet(); 
                len = 0; 
 
                if(ptHSCB->TotalLen[0][i] != ptHSCB->SendLen[0][i] ) 
                { 
 
                    SendLen = ptHSCB->TotalLen[0][i] - ptHSCB->SendLen[0][i]; 
                    if(SendLen >1460*2) 
                    { 
                     /*   SendLen = min(SendLen , 
                            socket_check_sendbuf(ptHSCB->Sock[i])) ; 
                      */ 
                        SendLen = 1460*2; 
                    } 
 
                    len = send(ptHSCB->Sock[i] 
                        ,ptHSCB->File[0][i] + ptHSCB->SendLen[0][i] 
                        ,SendLen 
                        ,0); 
                    if(len < 0) 
                    {    // send destory 
                        HttpCloseStreamConnect((void*)ptHSCB, i); 
                        continue; 
                    } 
 
                    ptHSCB->SendLen[0][i] += len; 
                } 
 
                if(ptHSCB->TotalLen[0][i] == ptHSCB->SendLen[0][i]) 
                { 
 
 
                    SendLen = ptHSCB->TotalLen[1][i] - ptHSCB->SendLen[1][i]; 
                    if(SendLen >1460*2) 
                    {    /* 
                        SendLen = min(SendLen , 
                            socket_check_sendbuf(ptHSCB->Sock[i])) ; 
                         */ 
                        SendLen = 1460*2; 
                    } 
 
                    len = send(ptHSCB->Sock[i] 
                        ,ptHSCB->File[1][i] + ptHSCB->SendLen[1][i] 
                        ,SendLen 
                        ,0); 
                    if(len < 0) 
                    {    // send destory 
                        HttpCloseStreamConnect((void*)ptHSCB, i); 
                        continue; 
                    } 
 
                    ptHSCB->SendLen[1][i] += len; 
 
                    if(ptHSCB->SendLen[1][i] > TCP_SND_BUF - socket_check_sendbuf(ptHSCB->Sock[i])) 
                    { 
                        video_image_free(ptHSCB->File[0][i]); 
                        ptHSCB->File[0][i] = NULL; 
 
                        ptHSCB->File[0][i]       =   ptHSCB->File[1][i]; 
                        ptHSCB->TotalLen[0][i]   =   ptHSCB->TotalLen[1][i]; 
                        ptHSCB->SendLen[0][i]    =   ptHSCB->SendLen[1][i]; 
 
                        ptHSCB->File[1][i] = NULL; 
 
                    } 
 
 
                } 
 
 
 
 
            } 
            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)*/ 
 
} 
 
#if 0 
 
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_SOCKET; 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; 
        } 
 
        count =  select(maxfdp1, 0, &writeset, 0,&timeout); 
 
        for(i = 0; i < HTTP_MAX_SOCKET; i++) 
        { 
            if(ptHSCB->Sock[i] == INVALID_SOCKET 
              || ptHSCB->Stat[i] != HTTP_STREAM_STAT_SEN) 
                continue; 
 
            if( FD_ISSET(ptHSCB->Sock[i], &writeset) ) 
            { 
                ptHSCB->AccessTime[i]    = OSTimeGet(); 
                len = 0; 
                if(ptHSCB->File[i] != NULL) 
                { 
               /* 
              //INT32S                  SendLen; 
                    SendLen = ptHSCB->TotalLen[i] - ptHSCB->SendLen[i]; 
                    if(SendLen >1460) 
                    { 
                        SendLen = min(SendLen , 
                            socket_check_sendbuf(ptHSCB->Sock[i])) ; 
 
                        SendLen = (SendLen/1460)*1460; 
                    } 
 
                    len = send(ptHSCB->Sock[i] 
                        ,ptHSCB->File[i] + ptHSCB->SendLen[i] 
                        ,SendLen 
                        ,0); 
                        */ 
 
                    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]) 
                { 
                   //--- free image 
                    if(ptHSCB->File[i] != NULL) 
                    { 
                      video_image_free(ptHSCB->File[i]); 
 
                    } 
                   //--- 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)*/ 
 
} 
#endif 
//*********************************************** 
// HttpStreamInit(void *data) 
// Description  : INIT  GtHSCB 
// Parameters   : 
// Returns      : 
//*********************************************** 
void HttpStreamInit(void *data) 
{ 
    INT8U           i; 
    THttpStreamCtrlBlack *ptHSCB   =   &GtHSCB; 
 
    for(i = 0; i < HTTP_MAX_SOCKET; 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->PID[index]                   =   0xff; 
 
    ptHSCB->TotalLen[0][index]              =   0; 
    ptHSCB->SendLen[0][index]               =   0; 
    ptHSCB->File[0][index]                  =   NULL; 
    ptHSCB->TotalLen[1][index]              =   0; 
    ptHSCB->SendLen[1][index]               =   0; 
    ptHSCB->File[1][index]                  =   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[0][index] != NULL) 
    { 
 
        video_image_free(ptHSCB->File[0][index]); 
        ptHSCB->File[0][index] = NULL; 
    } 
    if(ptHSCB->File[1][index] != NULL) 
    { 
 
        video_image_free(ptHSCB->File[1][index]); 
        ptHSCB->File[1][index] = NULL; 
    } 
 
 
    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; 
    INT8U            i; 
    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 
    send_jpg.jpg_imag_width    =   Width; 
    send_jpg.jpg_imag_height   =   Height; 
    send_jpg.jpg_qual          =   Qual; 
    send_jpg.jpg_shp_smooth    =   0;      //disable shp & smooth 
    send_jpg.jpg_tv_msec       =   0;      //always wait image get 
 
    for(i = 0; i < 2; i++) 
    { 
        if(ptHSCB->File[i][index] == NULL) 
        { 
            video_image_get((void*)&send_jpg); 
            memcpy((char*)&extra_head, (char*)Video_Jpg_Sample_Head, 20); 
            extra_head.Jpg_Size  =  send_jpg.jpg_data_size; 
            extra_head.Qtable    =  send_jpg.jpg_qual; 
 
            extra_head.Width    =    send_jpg.jpg_imag_width ; 
            extra_head.Height   =    send_jpg.jpg_imag_height ; 
 
            ptHSCB->File[i][index]       =   send_jpg.jpg_line; 
            ptHSCB->TotalLen[i][index]   =   send_jpg.jpg_data_size    +   20; 
            ptHSCB->SendLen[i][index]    =   0; 
            memcpy(send_jpg.jpg_line, &extra_head , 20); 
        } 
    } 
} 
 
#endif  /*HTTP_OPEN*/