void * streamts_live_thread(void *data) { unsigned char * buf; int pid; int pids[MAXPIDS]; char cbuf[512]; char *bp; int fd = (int) data; FILE * fp; unsigned char demuxfd_count = 0; printf("Starting LIVE STREAM thread, fd %d\n", fd); fp = fdopen(fd, "r+"); if(fp == NULL) { perror("fdopen"); return 0; } writebuf_size = 0; cbuf[0] = 0; bp = &cbuf[0]; /* read one line */ while (bp - &cbuf[0] < (int) sizeof(cbuf)) { unsigned char c; int res = read(fd, &c, 1); if(res < 0) { perror("read"); return 0; } if ((*bp++ = c) == '\n') break; } *bp++ = 0; bp = &cbuf[0]; printf("stream: got %s\n", cbuf); /* send response to http client */ if (!strncmp(cbuf, "GET /", 5)) { fprintf(fp, "HTTP/1.1 200 OK\r\nServer: streamts (%s)\r\n\r\n", "ts" /*&argv[1][1]*/); fflush(fp); bp += 5; } else { printf("Received garbage\n"); return 0; } /* parse stdin / url path, start dmx filters */ do { int res = sscanf(bp, "%x", &pid); if(res == 1) { printf("New pid: 0x%x\n", pid); pids[demuxfd_count++] = pid; } } while ((bp = strchr(bp, ',')) && (bp++) && (demuxfd_count < MAXPIDS)); if(demuxfd_count == 0) { printf("No pids!\n"); return 0; } buf = (unsigned char *) malloc(IN_SIZE); if (buf == NULL) { perror("malloc"); return 0; } #ifdef AZBOX_GEN_1 cDemux * dmx[demuxfd_count]; for(int i = 0; i < demuxfd_count; i++) { dmx[i] = new cDemux(2); dmx[i]->Open(DMX_TP_CHANNEL, NULL, DMX_BUFFER_SIZE); dmx[i]->pesFilter(pids[i]); dmx[i]->Start(); } if(channel) cam0->setCaPmt(channel->getCaPmt(), 0, 3, true); // demux 0 + 1, update size_t pos; ssize_t r; ssize_t todo; int offset, pres; struct pollfd pfd; int dvrfd = open("/dev/dvb/adapter0/dvr0", O_RDONLY|O_NONBLOCK); if (dvrfd<1) { perror("[streamts] dvrfd: "); return 0; } pfd.fd = dvrfd; pfd.events = POLLIN|POLLERR; pfd.revents = 0; while (!exit_flag) { todo = IN_SIZE; pos = 0; if ((pres=poll (&pfd, 1, 15000))>0) { if (!(pfd.revents&POLLIN)) { printf ("[streamts]: PANIC: error reading from demux, bailing out\n"); } while ((!exit_flag) && (todo)) { r = read(dvrfd, buf+pos, todo); if (r > 0) { pos += r; todo -= r; } } if(!exit_flag) { offset = sync_byte_offset(buf, IN_SIZE); if (offset == -1) continue; packet_stdout(fd, buf + offset, IN_SIZE - offset, NULL); } } else if (!pres) { printf ("[streamts]: timeout from demux\n"); } } close(dvrfd); for(int i = 0; i < demuxfd_count; i++) { dmx[i]->Stop(); dmx[i]->Close(); delete dmx[i]; } #else cDemux * dmx = new cDemux(2); dmx->Open(DMX_TP_CHANNEL, NULL, DMX_BUFFER_SIZE); dmx->pesFilter(pids[0]); for(int i = 1; i < demuxfd_count; i++) dmx->addPid(pids[i]); dmx->Start(); if(channel) cam0->setCaPmt(channel->getCaPmt(), 0, 3, true); // demux 0 + 1, update size_t pos; ssize_t r; ssize_t todo; int offset; while (!exit_flag) { todo = IN_SIZE; pos = 0; while ((!exit_flag) && (todo)) { r = dmx->Read(buf+pos, todo, 100); if (r > 0) { //printf("Read: %d\n", r); pos += r; todo -= r; } else usleep(1000); } if(!exit_flag) { //packet_stdout(fd, buf, IN_SIZE, NULL); /* make sure to start with a ts header */ offset = sync_byte_offset(buf, IN_SIZE); if (offset == -1) continue; packet_stdout(fd, buf + offset, IN_SIZE - offset, NULL); } } printf("Exiting LIVE STREAM thread, fd %d\n", fd); if(channel) cam0->setCaPmt(channel->getCaPmt(), 0, 1, true); // demux 0, update delete dmx; #endif //AZBOX_GEN_1 free(buf); close(fd); return 0; }
void streamts_file_thread(void *data) { int dvrfd; unsigned char * buf; char cbuf[512]; char *bp; unsigned char mode = 0; char tsfile[IN_SIZE]; int tsfilelen = 0; int fileslice = 0; int i = 0; int fd = (int) data; buf = (unsigned char *) malloc(IN_SIZE); if (buf == NULL) { perror("malloc"); return; } bp = &cbuf[0]; /* read one line */ while (bp - &cbuf[0] < IN_SIZE) { unsigned char c; read(fd, &c, 1); if ((*bp++ = c) == '\n') break; } *bp++ = 0; bp = &cbuf[0]; /* send response to http client */ if (!strncmp(cbuf, "GET /", 5)) { printf("HTTP/1.1 200 OK\r\nServer: streamts (%s)\r\n\r\n", "ts" /*&argv[1][1]*/); fflush(stdout); bp += 5; } /* ts filename */ int j = 0; i = 0; while (i < (int) strlen(bp) - 3) { if ((bp[i] == '.') && (bp[i + 1] == 't') && (bp[i + 2] == 's')) { tsfile[j] = bp[i]; tsfile[j + 1] = bp[i + 1]; tsfile[j + 2] = bp[i + 2]; tsfile[j + 3] = '\0'; break; } else if ((bp[i] == '%') && (bp[i + 1] == '2') && (bp[i + 2] == '0')) { tsfile[j++] = ' '; i += 3; } else tsfile[j++] = bp[i++]; } tsfilelen = strlen(tsfile); /* open ts file */ if ((dvrfd = open(tsfile, O_RDONLY)) < 0) { free(buf); return; } size_t pos; ssize_t r; while (!exit_flag) { /* always read IN_SIZE bytes */ for (pos = 0; pos < IN_SIZE; pos += r) { r = read(dvrfd, buf + pos, IN_SIZE - pos); if (r == -1) { /* Error */ exit_flag = 1; break; } else if (r == 0) { /* End of file */ if (mode == 3) { close(dvrfd); sprintf(&tsfile[tsfilelen], ".%03d", ++fileslice); dvrfd = open(tsfile, O_RDONLY); } if ((dvrfd == -1) || (mode != 3)) { exit_flag = 1; break; } } } packet_stdout(fd, buf, pos, NULL); } close(dvrfd); free(buf); return; }
void * streamts_live_thread(void * data) { unsigned char * buf; int pid; int pids[MAXPIDS]; char cbuf[512]; char *bp; int fd = (int) (long)data; FILE * fp; unsigned char demuxfd_count = 0; dprintf(DEBUG_NORMAL, "streamts_live_thread: Starting LIVE STREAM thread, fd %d\n", fd); fp = fdopen(fd, "r+"); if(fp == NULL) { perror("fdopen"); return 0; } writebuf_size = 0; cbuf[0] = 0; bp = &cbuf[0]; // read one line while (bp - &cbuf[0] < (int) sizeof(cbuf)) { unsigned char c; int res = read(fd, &c, 1); if(res < 0) { perror("read"); return 0; } if ((*bp++ = c) == '\n') break; } *bp++ = 0; bp = &cbuf[0]; dprintf(DEBUG_NORMAL, "streamts_live_thread: stream: got %s\n", cbuf); // send response to http client if (!strncmp(cbuf, "GET /", 5)) { fprintf(fp, "HTTP/1.1 200 OK\r\nServer: streamts (%s)\r\n\r\n", "ts" /*&argv[1][1]*/); fflush(fp); bp += 5; } else { dprintf(DEBUG_NORMAL, "Received garbage\n"); return 0; } t_channel_id stream_channel_id = 0; CZapitChannel * stream_channel = NULL; bp = &cbuf[5]; if (sscanf(bp, "id=%llx", &stream_channel_id) == 1) { if(g_Zapit->zapTo_record(stream_channel_id&0xFFFFFFFFFFFFULL) == 0) { stream_channel = find_channel_tozap(stream_channel_id&0xFFFFFFFFFFFFULL, false); pids[0] = 0; if(stream_channel != NULL) { pids[1] = stream_channel->getPmtPid(); pids[2] = stream_channel->getVideoPid(); pids[3] = stream_channel->getPreAudioPid(); } else return 0; } else return 0; } else { // parse stdin / url path, start dmx filters do { int res = sscanf(bp, "%x", &pid); if(res == 1) { dprintf(DEBUG_NORMAL, "streamts_live_thread: New pid: 0x%x\n", pid); pids[demuxfd_count++] = pid; } } while ((bp = strchr(bp, ',')) && (bp++) && (demuxfd_count < MAXPIDS)); if(demuxfd_count == 0) { dprintf(DEBUG_NORMAL, "streamts_live_thread: No pids!\n"); return 0; } } buf = (unsigned char *) malloc(IN_SIZE); if (buf == NULL) { perror("malloc"); return 0; } cDemux * dmx = new cDemux(); #if defined (PLATFORM_COOLSTREAM) dmx->Open(DMX_TP_CHANNEL); #else dmx->Open( DMX_TP_CHANNEL, 3 * 3008 * 62, live_fe); #endif dmx->pesFilter(pids[0]); for(int i = 1; i < demuxfd_count; i++) dmx->addPid(pids[i]); ssize_t r; while (!exit_flag) { r = dmx->Read(buf, IN_SIZE, 100); if(r > 0) packet_stdout(fd, buf, r, NULL); } dprintf(DEBUG_NORMAL, "streamts_live_thread: Exiting LIVE STREAM thread, fd %d\n", fd); #if !defined (PLATFORM_COOLSTREAM) for(int i = 1; i < demuxfd_count; i++) dmx->removePid(pids[i]); #endif dmx->Stop(); delete dmx; free(buf); close(fd); return 0; }