I want to write a simple function to re-combine / reconstruct/depayload rtp packets. For testing, I will just use an jpeg image, break it apart in RTP packets then try to recombine them.
The thing is, i am not too sure on how to do that. Can someone give me some direction ?
Here is the snipet code on rtp packet
/**
* The same timestamp MUST appear in each fragment of a given frame.
* The RTP marker bit MUST be set in the last packet of a frame.
* @param[in] *udp The UDP socket to send the RTP packet over
* @param[in] *Jpeg JPEG encoded image byte buffer
* @param[in] JpegLen The length of the byte buffer
* @param[in] m_SequenceNumber RTP sequence number
* @param[in] m_Timestamp Timestamp of the image in usec
* @param[in] m_offset 3 byte fragmentation offset for fragmented images
* @param[in] marker_bit RTP marker bit
* @param[in] w The width of the JPEG image
* @param[in] h The height of the image
* @param[in] format_code 0 for YUV422 and 1 for YUV421
* @param[in] quality_code The JPEG encoding quality
* @param[in] has_dri_header Whether we have an DRI header or not
*/
static void rtp_packet_send(
struct UdpSocket *udp,
uint8_t *Jpeg, int JpegLen,
uint32_t m_SequenceNumber, uint32_t m_Timestamp,
uint32_t m_offset, uint8_t marker_bit,
int w, int h,
uint8_t format_code, uint8_t quality_code,
uint8_t has_dri_header)
{
#define KRtpHeaderSize 12 // size of the RTP header
#define KJpegHeaderSize 8 // size of the special JPEG payload header
uint8_t RtpBuf[2048];
int RtpPacketSize = JpegLen + KRtpHeaderSize + KJpegHeaderSize;
memset(RtpBuf, 0x00, sizeof(RtpBuf));
/*
The RTP header has the following format:
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|V=2|P|X| CC |M| PT | sequence number |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| timestamp |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| synchronization source (SSRC) identifier |
+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
| contributing source (CSRC) identifiers |
| .... |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* */
m_Timestamp *= 9 / 100; // convert timestamp to units of 1 / 90000 Hz
// Prepare the 12 byte RTP header
RtpBuf[0] = 0x80; // RTP version
RtpBuf[1] = 0x1a + (marker_bit << 7); // JPEG payload (26) and marker bit
RtpBuf[2] = m_SequenceNumber >> 8;
RtpBuf[3] = m_SequenceNumber & 0x0FF; // each packet is counted with a sequence counter
RtpBuf[4] = (m_Timestamp & 0xFF000000) >> 24; // each image gets a timestamp
RtpBuf[5] = (m_Timestamp & 0x00FF0000) >> 16;
RtpBuf[6] = (m_Timestamp & 0x0000FF00) >> 8;
RtpBuf[7] = (m_Timestamp & 0x000000FF);
RtpBuf[8] = 0x13; // 4 byte SSRC (sychronization source identifier)
RtpBuf[9] = 0xf9; // we just an arbitrary number here to keep it simple
RtpBuf[10] = 0x7e;
RtpBuf[11] = 0x67;
/* JPEG header", are as follows:
*
* http://tools.ietf.org/html/rfc2435
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Type-specific | Fragment Offset |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Type | Q | Width | Height |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
// Prepare the 8 byte payload JPEG header
RtpBuf[12] = 0x00; // type specific
RtpBuf[13] = (m_offset & 0x00FF0000) >> 16; // 3 byte fragmentation offset for fragmented images
RtpBuf[14] = (m_offset & 0x0000FF00) >> 8;
RtpBuf[15] = (m_offset & 0x000000FF);
RtpBuf[16] = 0x00; // type: 0 422 or 1 421
RtpBuf[17] = 60; // quality scale factor
RtpBuf[16] = format_code; // type: 0 422 or 1 421
if (has_dri_header) {
RtpBuf[16] |= 0x40; // DRI flag
}
RtpBuf[17] = quality_code; // quality scale factor
RtpBuf[18] = w / 8; // width / 8 -> 48 pixel
RtpBuf[19] = h / 8; // height / 8 -> 32 pixel
// append the JPEG scan data to the RTP buffer
memcpy(&RtpBuf[20], Jpeg, JpegLen);
//udp_socket_send_dontwait(udp, RtpBuf, RtpPacketSize); // uncomment after done testing reconstruct rtp packet
};
struct JPEGDepay{
int width;
int height;
int framerate;
int framerate_denom;
bool discontl;
};
the struct JPEGdepay is just there because i have no idea what to do next.
User contributions licensed under CC BY-SA 3.0