#include "stream.h" #include #include #include #include #include #include #include "metafile.h" #include "epoll.h" #include "log.h" #include "main.h" #include "packet.h" // stream is locked void stream_close(stream_t *stream) { if (stream->fd == -1) return; epoll_del(stream->fd); close(stream->fd); stream->fd = -1; } void stream_free(stream_t *stream) { g_slice_free1(sizeof(*stream), stream); } static void stream_handler(handler_t *handler) { stream_t *stream = handler->ptr; //dbg("poll event for %s", stream->name); pthread_mutex_lock(&stream->lock); if (stream->fd == -1) goto out; static const int maxbuflen = 65535; static const int alloclen = maxbuflen #ifdef AV_INPUT_BUFFER_PADDING_SIZE + AV_INPUT_BUFFER_PADDING_SIZE #endif #ifdef FF_INPUT_BUFFER_PADDING_SIZE + FF_INPUT_BUFFER_PADDING_SIZE #endif ; unsigned char *buf = malloc(alloclen); int ret = read(stream->fd, buf, maxbuflen); if (ret == 0) { ilog(LOG_INFO, "EOF on stream %s", stream->name); stream_close(stream); goto out; } else if (ret < 0) { ilog(LOG_INFO, "Read error on stream %s: %s", stream->name, strerror(errno)); stream_close(stream); goto out; } // got a packet pthread_mutex_unlock(&stream->lock); packet_process(stream, buf, ret); return; out: pthread_mutex_unlock(&stream->lock); } // mf is locked static stream_t *stream_get(metafile_t *mf, unsigned long id) { if (mf->streams->len <= id) g_ptr_array_set_size(mf->streams, id + 1); stream_t *ret = g_ptr_array_index(mf->streams, id); if (ret) goto out; ret = g_slice_alloc0(sizeof(*ret)); g_ptr_array_index(mf->streams, id) = ret; pthread_mutex_init(&ret->lock, NULL); ret->fd = -1; ret->id = id; ret->metafile = mf; out: return ret; } // mf is locked void stream_open(metafile_t *mf, unsigned long id, char *name) { dbg("opening stream %lu/%s", id, name); stream_t *stream = stream_get(mf, id); stream->name = g_string_chunk_insert(mf->gsc, name); char fnbuf[PATH_MAX]; snprintf(fnbuf, sizeof(fnbuf), "%s/%s/%s", PROC_DIR, mf->parent, name); stream->fd = open(fnbuf, O_RDONLY | O_NONBLOCK); if (stream->fd == -1) { ilog(LOG_ERR, "Failed to open kernel stream %s: %s", fnbuf, strerror(errno)); return; } // add to epoll stream->handler.ptr = stream; stream->handler.func = stream_handler; epoll_add(stream->fd, EPOLLIN, &stream->handler); }