#include "rtp-payload-helper.h" #include #include #include #include #include "rtp-param.h" void* rtp_payload_helper_create(struct rtp_payload_t* handler, void* cbparam) { struct rtp_payload_helper_t* helper; helper = (struct rtp_payload_helper_t*)calloc(1, sizeof(*helper)); if (!helper) return NULL; memcpy(&helper->handler, handler, sizeof(helper->handler)); helper->maxsize = RTP_PAYLOAD_MAX_SIZE; helper->cbparam = cbparam; helper->__flags = -1; return helper; } void rtp_payload_helper_destroy(void* p) { struct rtp_payload_helper_t* helper; helper = (struct rtp_payload_helper_t*)p; if (helper->ptr) free(helper->ptr); #if defined(_DEBUG) || defined(DEBUG) memset(helper, 0xCC, sizeof(*helper)); #endif free(helper); } int rtp_payload_check(struct rtp_payload_helper_t* helper, const struct rtp_packet_t* pkt) { int lost; // next frame lost packet flags // first packet only if (-1 == helper->__flags) { // TODO: first packet lost ??? helper->__flags = 0; helper->seq = (uint16_t)(pkt->rtp.seq - 1); // disable packet lost helper->timestamp = pkt->rtp.timestamp + 1; // flag for new frame } lost = 0; // check sequence number if ((uint16_t)pkt->rtp.seq != (uint16_t)(helper->seq + 1)) { lost = 1; // helper->size = 0; helper->lost = 1; // helper->flags |= RTP_PAYLOAD_FLAG_PACKET_LOST; // helper->timestamp = pkt->rtp.timestamp; } helper->seq = (uint16_t)pkt->rtp.seq; // check timestamp if (pkt->rtp.timestamp != helper->timestamp) { rtp_payload_onframe(helper); // lost: // 0 - packet lost before timestamp change // 1 - packet lost on timestamp changed, can't known losted packet is at old packet tail or new packet start, so // two packets mark as packet lost if (0 != lost) helper->lost = lost; } helper->timestamp = pkt->rtp.timestamp; return 0; } /** * @brief rtp_payload_write * @param helper 缓存每个au解析出来的数据 * @param pkt * @return */ int rtp_payload_write(struct rtp_payload_helper_t* helper, const struct rtp_packet_t* pkt) { int size; size = helper->size + pkt->payloadlen; if (size > helper->maxsize || size < 0) return -EINVAL; if (size > helper->capacity) { void* ptr; size += size / 4 > 16000 ? size / 4 : 16000; ptr = realloc(helper->ptr, size); if (!ptr) { // helper->flags |= RTP_PAYLOAD_FLAG_PACKET_LOST; helper->lost = 1; // helper->size = 0; return -ENOMEM; } helper->ptr = (uint8_t*)ptr; helper->capacity = size; } assert(helper->capacity >= helper->size + pkt->payloadlen); memcpy(helper->ptr + helper->size, pkt->payload, pkt->payloadlen); helper->size += pkt->payloadlen; return 0; } int rtp_payload_onframe(struct rtp_payload_helper_t* helper) { int r; r = 0; if (helper->size > 0 #if !defined(RTP_ENABLE_COURRUPT_PACKET) && 0 == helper->lost #endif ) { // previous packet done r = helper->handler.packet(helper->cbparam, helper->ptr, helper->size, helper->timestamp, helper->__flags | (helper->lost ? RTP_PAYLOAD_FLAG_PACKET_CORRUPT : 0)); // RTP_PAYLOAD_FLAG_PACKET_LOST: miss helper->__flags &= ~RTP_PAYLOAD_FLAG_PACKET_LOST; // clear packet lost flag } // set packet lost flag on next frame if (helper->lost) helper->__flags |= RTP_PAYLOAD_FLAG_PACKET_LOST; // new frame start helper->lost = 0; helper->size = 0; return r; }