/* * * This file is part of bufferpool * * Copyright (C) 2007 by LScube team * See AUTHORS for more details * * bufferpool is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * bufferpool is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with bufferpool; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * */ /* * Fenice's bufferpool is projected to support ONE AND ONLY ONE producer * and many consumers. * Each consumer have it's own BPConsumer structure that is NOT SHARED * with others readers. * So the only struct that must be locked with mutexes is BPBuffer. * */ #ifndef BUFFERPOOL_H #define BUFFERPOOL_H #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #include #include #include #include //XXX remove them #define omsbuff_min(x,y) ((x) < (y) ? (x) : (y)) #define omsbuff_max(x,y) ((x) > (y) ? (x) : (y)) #define BPBUFF_MEM_PAGE 9 #define BPBUFFER_DEFAULT_DIM BPBUFF_MEM_PAGE #define BPSLOT_DATASIZE 65000 #define BPBUFF_SHM_CTRLNAME "Buffer" #define BPBUFF_SHM_SLOTSNAME "Slots" #define BPBUFF_SHM_PAGE BPBUFF_MEM_PAGE // 9 #ifndef FNC_LOG_DEBUG #define FNC_LOG_DEBUG 4 #endif #ifndef FNC_LOG_ERR #define FNC_LOG_ERR 1 #endif #ifndef FNC_LOG_FATAL #define FNC_LOG_FATAL 0 #endif #ifndef ERR_ALLOC #define ERR_ALLOC -4 #endif #ifndef ERR_NOERROR #define ERR_NOERROR 0 #endif #ifndef PATH_MAX #define PATH_MAX 4096 #endif #define bp_lock(buffer) pthread_mutex_lock(&buffer->control->syn) #define bp_unlock(buffer) pthread_mutex_unlock(&buffer->control->syn) typedef ptrdiff_t BPSlotPtr; typedef struct { uint16_t refs; int16_t seq_delta; /*! delta to latest sequence number */ uint64_t slot_seq; /*! monotone identifier of slot (NOT RTP seq) */ double timestamp; double sendts; /*! send time of pkt */ uint32_t rtp_time; // if != 0 it contains the calculated rtp timestamp uint8_t data[BPSLOT_DATASIZE]; uint32_t data_size; uint8_t marker; ptrdiff_t next; } BPSlot; typedef struct { uint16_t refs; /*! n.Consumers that share the buffer */ uint32_t nslots; BPSlotPtr write_pos; /*! last write position */ pthread_mutex_t syn; } BPControl; typedef enum { buff_local = 0, buff_shm } BPBufferType; /*! * Buffer struct. * the pointers have different meaning if we use normally allocated memory * or shared memory. * Using a shared memory buffer pointer will be offsets relative to the * beginning of SHM. * This way the two processes can add the address returned by mmap to obtain * the absolute address. * */ typedef struct { BPBufferType type; //! whether buffer is on shared memory or not; BPControl *control; BPSlot *slots; /*! Buffer head */ uint32_t known_slots; /*!< last known number of slots. This member is only useful for SHM buffer. */ char filename[PATH_MAX]; //! SHM object file // int fd; /*! pointer to File descriptor of incoming data*/ } BPBuffer; typedef struct { BPSlotPtr read_pos; /*! read position */ BPSlotPtr last_read_pos; /*! last read position. used for managing the slot addition */ uint64_t last_seq; BPBuffer *buffer; int32_t frames; int32_t first_rtpseq; int64_t first_rtptime; // pthread_mutex_t mutex; } BPConsumer; /*! API definitions*/ BPBuffer *bp_new(uint32_t); BPConsumer *bp_ref(BPBuffer *); void bp_unref(BPConsumer *); int bp_read(BPConsumer *, uint32_t *, uint8_t *, uint8_t *, uint32_t *); BPSlot *bp_getreader(BPConsumer *); int bp_gotreader(BPConsumer *); int bp_write(BPBuffer *, int16_t, double, uint32_t, uint8_t, uint8_t *, uint32_t); BPSlot *bp_getslot(BPBuffer *); BPSlot *bp_addpage(BPBuffer *, BPSlot *); //BPSlot *bp_slotadd(BPBuffer *, BPSlot *); void bp_free(BPBuffer *); int bp_isempty(BPConsumer *); double bp_nextts(BPConsumer *); // Shared Memory Bufferpool BPBuffer *bp_shm_create(char *, uint32_t); BPBuffer *bp_shm_map(char *); BPSlot *bp_shm_addpage(BPBuffer *); int bp_shm_remap(BPBuffer *); // int bp_shm_refresh(BPBuffer *); #define bp_shm_refresh(oms_buffer) \ (((oms_buffer->type == buff_shm) && \ (oms_buffer->known_slots != oms_buffer->control->nslots)) ? \ bp_shm_remap(oms_buffer) : 0) int bp_shm_unmap(BPBuffer *); int bp_shm_destroy(BPBuffer *); // shared memory names char *bp_ipc_name(const char *, const char *); typedef void (*bp_log_t)(int, const char*, va_list); void bp_log_init(bp_log_t fn); void bp_log(int level, const char *fmt, ...); // BPSlotPtr manipulation #define BPtoSlot(b, p) \ ((p<0) ? NULL : (&b->slots[p])) //! used when a pointer could be NULL, // otherwise we'll use buffe->slots[index] #define BPtoSlotPtr(b, p) (p ? p - b->slots : -1) // dump for debug #if ENABLE_DUMPBUFF void bp_dump(BPConsumer *, BPBuffer *); #else #define bp_dump(x, y) #endif #endif