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

68 lines
1.6 KiB
C++

/// RFC2250 3. Encapsulation of MPEG Elementary Streams (p4)
#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>
#define MPEG2VIDEO_EXTENSION_HEADER 0x04
static int rtp_decode_mpeg2es(void* p, const void* packet, int bytes)
{
int n;
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;
if (RTP_PAYLOAD_MP3 != pkt.rtp.pt && RTP_PAYLOAD_MPV != pkt.rtp.pt)
{
assert(0);
return -EINVAL;
}
rtp_payload_check(helper, &pkt);
// save payload
if (!helper->lost)
{
n = 4; // skip 3.4 MPEG Video-specific header
if (RTP_PAYLOAD_MPV == pkt.rtp.pt && (((uint8_t*)pkt.payload)[4] & MPEG2VIDEO_EXTENSION_HEADER))
n += 4; // 3.4.1 MPEG-2 Video-specific header extension
assert(pkt.payloadlen > 4);
if (pkt.payload && pkt.payloadlen > n)
{
pkt.payload = (uint8_t*)pkt.payload + n;
pkt.payloadlen -= n;
rtp_payload_write(helper, &pkt);
}
}
// M bit: For video, set to 1 on packet containing MPEG frame end code, 0 otherwise.
// For audio, set to 1 on first packet of a "talk-spurt," 0 otherwise.
if (pkt.rtp.m && RTP_PAYLOAD_MPV == pkt.rtp.pt)
{
rtp_payload_onframe(helper);
}
return helper->lost ? 0 : 1; // packet handled
}
struct rtp_payload_decode_t *rtp_mpeg1or2es_decode()
{
static struct rtp_payload_decode_t unpacker = {
rtp_payload_helper_create,
rtp_payload_helper_destroy,
rtp_decode_mpeg2es,
};
return &unpacker;
}