#include "avpacket-queue.h" #include "sys/sync.hpp" #include struct avpacket_queue_t { std::queue::size_type maxsize; std::queue q; ThreadLocker locker; ThreadEvent event; }; struct avpacket_queue_t* avpacket_queue_create(int size) { struct avpacket_queue_t* q = new struct avpacket_queue_t; q->maxsize = size; return q; } void avpacket_queue_destroy(struct avpacket_queue_t* q) { avpacket_queue_clear(q); delete q; } void avpacket_queue_clear(struct avpacket_queue_t* q) { AutoThreadLocker locker(q->locker); while (!q->q.empty()) { struct avpacket_t* pkt = q->q.front(); avpacket_release(pkt); q->q.pop(); } } int avpacket_queue_count(struct avpacket_queue_t* q) { AutoThreadLocker locker(q->locker); return (int)q->q.size(); } int avpacket_queue_pop(struct avpacket_queue_t* q) { struct avpacket_t* pkt; { AutoThreadLocker locker(q->locker); if (q->q.empty()) return -1; pkt = q->q.front(); q->q.pop(); q->event.Signal(); } avpacket_release(pkt); return 0; } struct avpacket_t* avpacket_queue_front(struct avpacket_queue_t* q) { struct avpacket_t* pkt; AutoThreadLocker locker(q->locker); if (q->q.empty()) return NULL; pkt = q->q.front(); avpacket_addref(pkt); return pkt; } int avpacket_queue_push(struct avpacket_queue_t* q, struct avpacket_t* pkt) { AutoThreadLocker locker(q->locker); if (q->q.size() >= q->maxsize) return -1; avpacket_addref(pkt); q->q.push(pkt); q->event.Signal(); return 0; } struct avpacket_t* avpacket_queue_front_wait(struct avpacket_queue_t* q, int ms) { q->locker.Lock(); if (q->q.empty()) { q->locker.Unlock(); if (0 != q->event.TimeWait(ms)) return NULL; q->locker.Lock(); } if (q->q.empty()) { q->locker.Unlock(); return NULL; } struct avpacket_t* pkt = q->q.front(); avpacket_addref(pkt); q->locker.Unlock(); return pkt; } int avpacket_queue_push_wait(struct avpacket_queue_t* q, struct avpacket_t* pkt, int ms) { q->locker.Lock(); if (q->q.size() >= q->maxsize) { q->locker.Unlock(); if (0 != q->event.TimeWait(ms)) return -1; q->locker.Lock(); } if (q->q.size() >= q->maxsize) { q->locker.Unlock(); return -1; } avpacket_addref(pkt); q->q.push(pkt); q->locker.Unlock(); return 0; }