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*/