224 lines
5.0 KiB
C
224 lines
5.0 KiB
C
#include <stdint.h>
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <rtthread.h>
|
|
#include <finsh.h>
|
|
#include <dfs_posix.h>
|
|
#include <sys/socket.h>
|
|
#include "include.h"
|
|
#include "net.h"
|
|
#include "typedef.h"
|
|
#include "arm_arch.h"
|
|
#include "uart_pub.h"
|
|
#include "rtos_pub.h"
|
|
#include "error.h"
|
|
#include "video_transfer.h"
|
|
#include "test_config.h"
|
|
|
|
#ifdef WEB_CAMERA_TEST
|
|
#define MJPEG_BOUNDARY "boundarydonotcross"
|
|
#define MAX_BUF_SIZE 40*1024
|
|
static int g_mjpeg_stop = 0;
|
|
static char g_send_buf[1024];
|
|
|
|
int send_first_response(int client)
|
|
{
|
|
g_send_buf[0] = 0;
|
|
|
|
rt_snprintf(g_send_buf, 1024,
|
|
"HTTP/1.0 200 OK\r\n"
|
|
"Connection: close\r\n"
|
|
"Server: MJPG-Streamer/0.2\r\n"
|
|
"Cache-Control: no-store, no-cache, must-revalidate, pre-check=0,"
|
|
" post-check=0, max-age=0\r\n"
|
|
"Pragma: no-cache\r\n"
|
|
"Expires: Mon, 3 Jan 2000 12:34:56 GMT\r\n"
|
|
"Content-Type: multipart/x-mixed-replace;boundary="
|
|
MJPEG_BOUNDARY "\r\n"
|
|
"\r\n"
|
|
"--" MJPEG_BOUNDARY "\r\n");
|
|
if (send(client, g_send_buf, strlen(g_send_buf), 0) < 0)
|
|
{
|
|
close(client);
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int mjpeg_send_stream(int client, void *data, int size)
|
|
{
|
|
g_send_buf[0] = 0;
|
|
|
|
if (!g_mjpeg_stop)
|
|
{
|
|
snprintf(g_send_buf, 1024,
|
|
"Content-Type: image/jpeg\r\n"
|
|
"Content-Length: %d\r\n"
|
|
"\r\n", size);
|
|
if (send(client, g_send_buf, strlen(g_send_buf), 0) < 0)
|
|
{
|
|
close(client);
|
|
return -1;
|
|
}
|
|
|
|
if (send(client, data, size, 0) < 0)
|
|
{
|
|
close(client);
|
|
return -1;
|
|
}
|
|
|
|
g_send_buf[0] = 0;
|
|
snprintf(g_send_buf, 1024, "\r\n--" MJPEG_BOUNDARY "\r\n");
|
|
if (send(client, g_send_buf, strlen(g_send_buf), 0) < 0)
|
|
{
|
|
close(client);
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
void mjpeg_server_thread(void *arg)
|
|
{
|
|
int on;
|
|
int srv_sock = -1;
|
|
int fream_length=0;
|
|
struct sockaddr_in addr;
|
|
socklen_t sock_len = sizeof(struct sockaddr_in);
|
|
|
|
int bufsz = 50 * 1024;
|
|
uint8_t *buf = (uint8_t *) malloc (MAX_BUF_SIZE);
|
|
|
|
if (!buf)
|
|
{
|
|
rt_kprintf("no buffer yet!\n");
|
|
return ;
|
|
}
|
|
|
|
|
|
srv_sock = socket(AF_INET, SOCK_STREAM, 0);
|
|
if (srv_sock < 0)
|
|
{
|
|
rt_kprintf("mjpeg_server: create server socket failed due to (%s)\n",
|
|
strerror(errno));
|
|
goto exit;
|
|
}
|
|
|
|
bzero(&addr, sock_len);
|
|
addr.sin_family = AF_INET;
|
|
addr.sin_port = htons(80);
|
|
addr.sin_addr.s_addr = INADDR_ANY;
|
|
|
|
/* ignore "socket already in use" errors */
|
|
on = 1;
|
|
lwip_setsockopt(srv_sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
|
|
lwip_setsockopt(srv_sock, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on));
|
|
|
|
if (bind(srv_sock, (struct sockaddr *)&addr, sock_len) != 0)
|
|
{
|
|
rt_kprintf("mjpeg_server: bind() failed due to (%s)\n",
|
|
strerror(errno));
|
|
goto exit;
|
|
}
|
|
|
|
if (listen(srv_sock , RT_LWIP_TCP_PCB_NUM) != 0)
|
|
{
|
|
rt_kprintf("mjpeg_server: listen() failed due to (%s)\n",
|
|
strerror(errno));
|
|
goto exit;
|
|
}
|
|
|
|
g_mjpeg_stop = 0;
|
|
while (!g_mjpeg_stop)
|
|
{
|
|
struct sockaddr_in client_addr;
|
|
int client = accept(srv_sock, (struct sockaddr *)&client_addr, &sock_len);
|
|
if (client < 0)
|
|
continue;
|
|
|
|
rt_kprintf("mjpeg_server: client connected\n");
|
|
if (send_first_response(client) < 0)
|
|
{
|
|
client = -1;
|
|
continue;
|
|
}
|
|
|
|
while (1)
|
|
{
|
|
fream_length = 0;
|
|
/* capture a jpeg frame */
|
|
fream_length = video_buffer_read_frame(buf, MAX_BUF_SIZE);
|
|
rt_kprintf("len:%d\r\n",fream_length);
|
|
if (fream_length !=0)
|
|
{
|
|
/* send out this frame */
|
|
if (mjpeg_send_stream(client, (void*)buf, fream_length) < 0)
|
|
{
|
|
rt_kprintf("client disconnected!\n");
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
exit:
|
|
if (srv_sock >= 0)
|
|
close(srv_sock);
|
|
if (buf)
|
|
{
|
|
free(buf);
|
|
buf=NULL;
|
|
}
|
|
}
|
|
|
|
int web_jpeg_stream(int argc, char** argv)
|
|
{
|
|
int frame_len;
|
|
unsigned char *jpg_buf = NULL;
|
|
if (argc != 2)
|
|
{
|
|
rt_kprintf("%s start|stop\n", argv[0]);
|
|
return 0;
|
|
}
|
|
|
|
video_buffer_open();
|
|
|
|
if (strcmp(argv[1], "start") == 0)
|
|
{
|
|
rt_kprintf("start web camerar\r\n");
|
|
rt_thread_t tid;
|
|
tid = rt_thread_create("jpeg_stream", mjpeg_server_thread, NULL, 2048,20, 10);
|
|
if (tid)
|
|
rt_thread_startup(tid);
|
|
}
|
|
else
|
|
{
|
|
g_mjpeg_stop = 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static void fream_set_video_param(int argc,char* argv[])
|
|
{
|
|
|
|
if(1==atoi(argv[1]))
|
|
{
|
|
video_transfer_set_video_param(QVGA_320_240,TYPE_20FPS);
|
|
}
|
|
else if(2==atoi(argv[1]))
|
|
{
|
|
video_transfer_set_video_param(VGA_640_480,TYPE_20FPS);
|
|
}
|
|
}
|
|
|
|
|
|
MSH_CMD_EXPORT(web_jpeg_stream, web_jpeg_stream server);
|
|
MSH_CMD_EXPORT(fream_set_video_param, fream_set_video_param cmd);
|
|
#endif
|