68 lines
1.6 KiB
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;
|
|
}
|