January 29, 2019 12:37AM
Hello all,

I tried to make a third-party module in nginx in order to support the ts stream in shared_memory. However, in my nginx handler function, it will output a FILE_SIZE ts steam in once. I want to enable "Transfer Encoding: chunked" in this function, so it can continuously send data to a client over a single HTTP connection that remains open indefinitely. Does the function " ngx_http_output_filter(r, &out)" can achieve this goal? or I should use another function to make it?

nginx version: 1.15.7
here is my nginx handler code:
static ngx_int_t ngx_http_ts_handler(ngx_http_request_t *r){

ngx_int_t rc;
ngx_buf_t *b;
ngx_chain_t out;
char uri[50] = {0};
static char ngx_ts_data[FILE_SIZE] = {0};

if (!(r->method & (NGX_HTTP_GET | NGX_HTTP_PUT ))) {
return NGX_HTTP_NOT_ALLOWED;
}

rc = ngx_http_discard_request_body(r);
if (rc != NGX_OK) return rc;

/* Set the Content-Type header. "text/html" */
r->headers_out.content_type.len = sizeof(TS_TYPE) - 1;
r->headers_out.content_type.data = (u_char *) TS_TYPE;
/* Allocate a new buffer for sending out the reply. */
b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t));
/* Insertion in the buffer chain. */
out.buf = b;
out.next = NULL;
memcpy(&uri, r-> uri_start , r-> uri_end-(r-> uri_start));
/*make http header*/
if (!strncmp(uri, "/VideoInput/", 12)){

int shm_fd;
uint32_t *pos_hdr;
int pos;
int cur_loc;
char *fifo_start;
int remain = 0;

shm_fd = open_output_shm(SHM_NAME);
g_shm_ptr = (char *)mmap(NULL, SHM_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0);
close(shm_fd);

pos_hdr = (uint32_t *)g_shm_ptr;
//chn = (int)(*pos_hdr & CHN_MASK);
pos = (int)(*pos_hdr & POS_MASK);

if (pos > (PACKET_SIZE * 100)) {
cur_loc = pos - (PACKET_SIZE * 100);
} else cur_loc = 0;

fifo_start = (char *)(pos_hdr + 1);
if (fifo_start[cur_loc] != 0x47) {
//json_object_set_new(jret, "TS", json_string("non-sync"));
memset(ngx_ts_data, 0, strlen(ngx_ts_data));
memcpy(ngx_ts_data,"TS non-sync", 11);
b->pos = (u_char *)ngx_ts_data;
b->last = (u_char *)ngx_ts_data + strlen(ngx_ts_data);
}else{

if( pos > FILE_SIZE ){

b->pos = (u_char *)(g_shm_ptr + 4);
b->last = (u_char *)(g_shm_ptr + 4) + FILE_SIZE;

}else{

remain = FILE_SIZE - pos;
memset(ngx_ts_data, 0, sizeof(ngx_ts_data)-1);
memcpy(ngx_ts_data, g_shm_ptr + (SHM_SIZE - remain), remain);
memcpy(&ngx_ts_data[remain], g_shm_ptr + 4, pos);
b->pos = (u_char *)ngx_ts_data;
b->last = (u_char *)ngx_ts_data + sizeof(ngx_ts_data)-1;
}
}

}else{
//json_object_set_new(jret, "TS", json_string("Nothing"));
memset(ngx_ts_data, 0, strlen(ngx_ts_data));
memcpy(ngx_ts_data,"No",2);
b->pos = (u_char *)ngx_ts_data;
b->last = (u_char *)ngx_ts_data + strlen(ngx_ts_data);
}

b->memory = 1; /* content is in read-only memory */
/* there will be no more buffers in the request */
b->last_buf = 1;
/* Sending the headers for the reply. */
r->headers_out.status = NGX_HTTP_OK; /* 200 status code */
rc = ngx_http_send_header(r); /* Send the headers */

if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) {
return rc;
}
/* Send the body, and return the status code of the output filter chain. */
return ngx_http_output_filter(r, &out);
}

Any help would be appreciated,

Pete
Subject Author Posted

http streaming with nginx module

Pete1103 January 29, 2019 12:37AM



Sorry, only registered users may post in this forum.

Click here to login

Online Users

Guests: 166
Record Number of Users: 8 on April 13, 2023
Record Number of Guests: 421 on December 02, 2018
Powered by nginx      Powered by FreeBSD      PHP Powered      Powered by MariaDB      ipv6 ready