8
#include <glib/glist.h>
13
extern struct http_server *hserver;
15
static void stream_remove_receiver(struct http_receiver_s *hr) {
16
struct stream_s *s=hr->stream;
17
struct http_connection *hc=hr->hc;
19
s->http_receiver=g_list_remove(s->http_receiver, hr);
22
logwrite(LOG_INFO, "stream_http: dropping connection to %s for %s",
23
inet_ntoa(hc->sin.sin_addr),
26
http_drop_connection(hc);
29
static int stream_cb_http(struct http_connection *hc, int cbtype, void *arg) {
33
struct http_receiver_s *hr;
34
struct stream_s *s=arg; /* HCB_QUERY returns http_url args */
36
hr=calloc(1, sizeof(struct http_receiver_s));
40
/* Put into stream output list */
41
s->http_receiver=g_list_append(s->http_receiver, hr);
44
/* Store http_receiver into http_connection structure */
48
http_header_start(hc, "200 OK", "application/octet-stream");
49
http_header_nocache(hc);
50
http_header_clength(hc, -1);
53
logwrite(LOG_INFO, "stream_http: connection from %s for %s",
54
inet_ntoa(hc->sin.sin_addr),
59
stream_remove_receiver(hc->arg);
66
#define SOUT_HTTP_CHUNK_SIZE 20000
68
int stream_init_http(struct stream_s *s) {
70
s->buffer=calloc(1, SOUT_HTTP_CHUNK_SIZE);
71
if (s->buffer == NULL)
74
s->hurl=calloc(2, sizeof(struct http_url));
77
s->hurl->cb=stream_cb_http;
78
s->hurl->arg=(void *) s;
80
http_register_url(hserver, s->hurl);
85
#define HTTP_MAX_QUEUED (200*1024)
86
#define HTTP_MAX_OVERFLOW 20
88
void stream_send_http_one(gpointer data, gpointer user_data) {
89
struct http_receiver_s *hr=data;
90
struct stream_s *s=user_data;
93
* Check how many bytes we already have queued on this
94
* HTTP connection. Users might connect from low bandwidth
95
* links not beeing able to transmit the full feed. We must
96
* avoid consuming all memory.
98
* If the situation persists too long we drop the connection
101
if (http_get_queue(hr->hc) > HTTP_MAX_QUEUED) {
103
if (hr->overflow > HTTP_MAX_OVERFLOW)
104
stream_remove_receiver(hr);
110
* We cant reuse evbuffer as they are empty after
111
* passing the the buffevent layer - Thus we recreate
112
* the buffer every time we send it out. This involes
113
* a little more memcpy as really necessary but for now
117
http_return_stream(hr->hc, s->buffer, s->buffervalid);
120
void stream_send_http(struct stream_s *s, uint8_t *tsp) {
121
/* Copy TS packet to packet buffer */
122
memcpy(&s->buffer[s->buffervalid], tsp, TS_PACKET_SIZE);
123
s->buffervalid+=TS_PACKET_SIZE;
125
/* check whether another packet would fit ? */
126
if (s->buffervalid + TS_PACKET_SIZE > SOUT_HTTP_CHUNK_SIZE) {
128
* If the output buffer is full - loop on all http sesssions
129
* and send out the buffer as a http chunk
131
g_list_foreach(s->http_receiver,
132
stream_send_http_one, (gpointer) s);