1..h文件
#ifndef decode_rtp_to_h264_h
#define decode_rtp_to_h264_h
uint8_t* decode_rtp_to_h264(uint8_t *rtp_buf, int len, int* retLength);
#endif
2..m文件
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include "decode_rtp_to_h264.h"
typedef struct{
/* byte 0 */
uint8_t type: 5; /* bit: 0~4 */
uint8_t nri: 2; /* bit: 5~6 */
uint8_t f: 1; /* bit: 7 */
} __attribute__ ((packed)) nalu_header_t; /* 1 bytes */
typedef struct{
/* byte 0 */
uint8_t type: 5;
uint8_t r: 1;
uint8_t e: 1;
uint8_t s: 1;
} __attribute__ ((packed)) fu_header_t; /* 1 bytes */
static uint8_t h264_buf[1024*1024*10];
static int h264_pos = -1;
uint32_t reversebytes_uint32t(uint32_t value){
return(value & 0x000000FFU) < ((value & 0x00FF0000U) >> 8 | (value & 0xFF000000U) >> 24);
}
static inline void h264_buf_write(void* data,int length){
if (h264_pos>=0) {
memcpy(h264_buf+h264_pos, data, length);
h264_pos += length;
}
}
uint8_t* decode_rtp_to_h264(uint8_t *rtp_buf, int len, int* retLength)
{
int header_len = 12;
int extension = rtp_buf[0] & (1<<4);
if(extension) {
uint32_t extLen = *((uint32_t*)(&rtp_buf[12]));
// uint32_t frameId = *((uint32_t*)(&rtp_buf[16]));
extLen = reversebytes_uint32t(extLen);
// frameId = CFSwapInt32HostToBig(frameId);
header_len += (extLen+1)*4;
}
static uint8_t ch0001[] = {0,0,0,1};
nalu_header_t *nalu_header;
fu_header_t *fu_header;
uint8_t h264_nal_header;
nalu_header = (nalu_header_t *)&rtp_buf[header_len];//前12个字节是RTP 头
if (nalu_header->type == 28) { /* FU-A */
fu_header = (fu_header_t *)&rtp_buf[header_len + 1];
if (fu_header->e == 1) { /* end of fu-a */ //分片结束
h264_buf_write(&rtp_buf[header_len + 2],len - (header_len + 2));
if (h264_pos>=0) {
*retLength = h264_pos;
h264_pos = -1;
// printf("分片结束=======");
return h264_buf;
}
} else if (fu_header->s == 1) { /* start of fu-a */ //分片开始
h264_pos = 0;
h264_buf_write(ch0001, 4);
h264_nal_header = (fu_header->type & 0x1f)
| (nalu_header->nri << 5)
| (nalu_header->f << 7);
h264_buf_write(&h264_nal_header,1);
// printf("分片开始=======%d",h264_nal_header);
h264_buf_write(&rtp_buf[header_len + 2], len - (header_len + 2));
} else { /* middle of fu-a */
h264_buf_write(&rtp_buf[header_len + 2], len - (header_len + 2));
// printf("分片中=======");
}
} else { /* nalu */
h264_pos = 0;
h264_buf_write(ch0001, 4);
h264_nal_header = (nalu_header->type & 0x1f)
| (nalu_header->nri << 5)
| (nalu_header->f << 7);
h264_buf_write(&h264_nal_header,1);
// printf("单包=======%d",h264_nal_header);
h264_buf_write(&rtp_buf[header_len + 1], len - (header_len + 1));
if (h264_pos>=0) {
*retLength = h264_pos;
h264_pos = -1;
return h264_buf;
}
}
return NULL;
}