stream-deploy/ZLM/3rdpart/media-server/librtp/payload/rtp-mp4a-latm-unpack.c

94 lines
2.2 KiB
C++

/// RFC3016 RTP Payload Format for MPEG-4 Audio/Visual Streams
/// RFC6416 RTP Payload Format for MPEG-4 Audio/Visual Streams
#include "rtp-packet.h"
#include "rtp-profile.h"
#include "rtp-payload-helper.h"
#include "rtp-payload-internal.h"
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <errno.h>
#include <errno.h>
static int rtp_decode_mp4a_latm(void* p, const void* packet, int bytes)
{
int len;
const uint8_t *ptr, *pend;
struct rtp_packet_t pkt;
struct rtp_payload_helper_t *helper;
helper = (struct rtp_payload_helper_t *)p;
if (!helper || 0 != rtp_packet_deserialize(&pkt, packet, bytes) || pkt.payloadlen < 4)
return -EINVAL;
rtp_payload_check(helper, &pkt);
// save payload
if (0 == helper->size)
{
ptr = (const uint8_t *)pkt.payload;
for (pend = ptr + pkt.payloadlen; ptr < pend; ptr += len)
{
// ISO/IEC 14496-3:200X(E)
// Table 1.44 - Syntax of PayloadLengthInfo() (p84)
// Table 1.45 - Syntax of PayloadMux()
for (len = 0; ptr < pend; ptr++)
{
len += *ptr;
if (255 != *ptr)
{
++ptr;
break;
}
}
if (ptr + len > pend)
{
assert(0);
//helper->size = 0;
helper->lost = 1;
//helper->flags |= RTP_PAYLOAD_FLAG_PACKET_LOST;
return -1; // invalid packet
}
// TODO: add ADTS/ASC ???
pkt.payload = ptr;
pkt.payloadlen = len;
rtp_payload_write(helper, &pkt);
if (ptr + len < pend || pkt.rtp.m)
{
rtp_payload_onframe(helper);
}
}
}
else
{
// RFC6416 6.3. Fragmentation of MPEG-4 Audio Bitstream (p17)
// It is RECOMMENDED to put one audioMuxElement in each RTP packet. If
// the size of an audioMuxElement can be kept small enough that the size
// of the RTP packet containing it does not exceed the size of the Path
// MTU, this will be no problem.If it cannot, the audioMuxElement
// SHALL be fragmented and spread across multiple packets.
rtp_payload_write(helper, &pkt);
if (pkt.rtp.m)
{
rtp_payload_onframe(helper);
}
}
return helper->lost ? 0 : 1; // packet handled
}
struct rtp_payload_decode_t *rtp_mp4a_latm_decode()
{
static struct rtp_payload_decode_t unpacker = {
rtp_payload_helper_create,
rtp_payload_helper_destroy,
rtp_decode_mp4a_latm,
};
return &unpacker;
}