static int http_server(void) { int server_fd = 0; int ctrl_fd = 0, ctrl_fd2 = 0; int ret, delay; struct pollfd *poll_table, *poll_entry; HTTPContext *c, *c_next; if(!(poll_table = av_mallocz_array(nb_max_http_connections + 1, sizeof(*poll_table)))) { http_log("Impossible to allocate a poll table handling %d connections.\n", nb_max_http_connections); return -1; } #if defined(PLUGIN_DVB) ctrl_fd = ff_ctl_open(1234); if (ctrl_fd < 0) { av_free(poll_table); return -1; } #endif if (my_http_addr.sin_port) { server_fd = socket_open_listen(&my_http_addr); if (server_fd < 0) { av_free(poll_table); return -1; } } if ( !server_fd) { http_log("HTTP disabled.\n"); av_free(poll_table); return -1; } #if defined(PLUGIN_SSDP) ssdp_fd = mcast_open(ssdp_ip, ssdp_port); if(ssdp_fd <= 0){ http_log("ssdp disabled\n"); } ssdp_notify(ssdp_fd, ssdp_ip, ssdp_port, "ssdp:alive"); #endif http_log("FFserver started.\n"); for(;;) { poll_entry = poll_table; #if defined(PLUGIN_DVB) if(ctrl_fd){ poll_entry->fd = ctrl_fd; poll_entry->events = POLLIN; poll_entry++; } if(ctrl_fd2){ poll_entry->fd = ctrl_fd2; poll_entry->events = POLLIN; if(ctl_msg_pending() > 0){ poll_entry->events |= POLLOUT; } poll_entry++; } #endif if (server_fd) { poll_entry->fd = server_fd; poll_entry->events = POLLIN; poll_entry++; } #if defined(PLUGIN_SSDP) if(ssdp_fd){ poll_entry->fd = ssdp_fd; poll_entry->events = POLLIN; poll_entry++; } #endif /* wait for events on each HTTP handle */ c = first_http_ctx; delay = 1500; while (c != NULL) { int fd; fd = c->fd; switch(c->state) { case HTTPSTATE_SEND_HEADER: c->poll_entry = poll_entry; poll_entry->fd = fd; poll_entry->events = POLLOUT; poll_entry++; break; case HTTPSTATE_SEND_DATA_HEADER: case HTTPSTATE_SEND_DATA: case HTTPSTATE_SEND_DATA_TRAILER: /*for TCP, we output as much as we can*/ c->poll_entry = poll_entry; poll_entry->fd = fd; poll_entry->events = POLLOUT; poll_entry++; break; case HTTPSTATE_WAIT_REQUEST: case HTTPSTATE_RECEIVE_DATA: case HTTPSTATE_WAIT_FEED: /* need to catch errors */ c->poll_entry = poll_entry; poll_entry->fd = fd; poll_entry->events = POLLIN;/* Maybe this will work */ poll_entry++; break; default: c->poll_entry = NULL; break; } c = c->next; } /* wait for an event on one connection. We poll at least every second to handle timeouts */ do { ret = poll(poll_table, poll_entry - poll_table, delay); if (ret < 0 && ff_neterrno() != AVERROR(EAGAIN) && ff_neterrno() != AVERROR(EINTR)) { av_free(poll_table); return -1; } } while (ret < 0); cur_time = av_gettime() / 1000; /* now handle the events */ for(c = first_http_ctx; c != NULL; c = c_next) { c_next = c->next; if (handle_connection(c) < 0) { log_connection(c); close_connection(c); } } poll_entry = poll_table; #if defined(PLUGIN_DVB) if(ctrl_fd){ if(poll_entry->revents & POLLIN){ ctrl_fd2 = ctl_msg_open(ctrl_fd); } poll_entry++; } if(ctrl_fd2 && poll_entry->fd == ctrl_fd2){ if(poll_entry->revents & POLLIN){ ctl_msg_recv(); ff_ctl_recv(ctl_msg_cb); }else if(poll_entry->revents & POLLOUT){ ctl_msg_send(); } poll_entry++; } #endif if(poll_entry->fd != server_fd){ printf("bad entry\n"); } if (server_fd) { if (poll_entry->revents & POLLIN) new_connection(server_fd, 0); poll_entry++; } #if defined(PLUGIN_SSDP) if (ssdp_fd) { if (poll_entry->revents & POLLIN) ssdp_response(ssdp_fd); poll_entry++; } #endif } }
/* main loop of the Streaming server */ static int start_event_loop(void) { int server_fd = 0, rtsp_server_fd = 0; int ret, delay; struct pollfd *poll_table, *poll_entry; RTSPContext *c, *c_next; if(!(poll_table = av_mallocz( 100 *sizeof(*poll_table)))) { http_log("Impossible to allocate a poll table handling %d connections.\n", 100); return -1; } if (my_rtsp_addr.sin_port) { rtsp_server_fd = socket_open_listen(&my_rtsp_addr); if (rtsp_server_fd < 0) { http_log("HTTP and RTSP disabled.\n"); return -1; } } printf("%s started.\n", program_name); for(;;) { poll_entry = poll_table; if (rtsp_server_fd) { poll_entry->fd = rtsp_server_fd; poll_entry->events = POLLIN; poll_entry++; } /* wait for events on each HTTP handle */ c = first_rtsp_ctx; //delay = 1000; delay = 10; while (c != NULL) { int fd; fd = c->fd; switch(c->state) { case RTSPSTATE_SEND_REPLY: case RTSPSTATE_SEND_PACKET: c->poll_entry = poll_entry; poll_entry->fd = fd; poll_entry->events = POLLOUT; poll_entry++; break; case RTPSTATE_SEND_DATA: /* for TCP, we output as much as we can * (may need to put a limit) */ if (strcmp(c->protocol, "RTP/UDP") == 0) { fd = c->udp_fd; } c->poll_entry = poll_entry; poll_entry->fd = fd; poll_entry->events = POLLOUT; poll_entry++; break; case RTSPSTATE_WAIT_REQUEST: /* need to catch errors */ c->poll_entry = poll_entry; poll_entry->fd = fd; poll_entry->events = POLLIN;/* Maybe this will work */ poll_entry++; break; default: c->poll_entry = NULL; break; } c = c->next; } /* wait for an event on one connection. We poll at least every second to handle timeouts */ do { ret = poll(poll_table, poll_entry - poll_table, delay); if (ret < 0) { printf ("poll errorr \n"); return -1; } } while (ret < 0); cur_time = av_gettime() / 1000; /* now handle the events */ for(c = first_rtsp_ctx; c != NULL; c = c_next) { c_next = c->next; if (handle_connection(c) < 0) { /* close and free the connection */ close_connection(c); } } // 처음에 rtsp_server_fd로 셋팅했던 거. 로 포인터 값 변경. poll_entry = poll_table; if (rtsp_server_fd) { /* new RTSP connection request ? */ if (poll_entry->revents & POLLIN) new_connection(rtsp_server_fd); } } }