生成h264 sdp文件

生成sdp文件

#define AV_BASE64_SIZE(x)  (((x)+2) / 3 * 4 + 1)
char *av_base64_encode(char *out, int out_size, const unsigned char *in, int in_size)
{
    static const char b64[] =
            "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
    char *ret, *dst;
    unsigned i_bits = 0;
    int i_shift = 0;
    int bytes_remaining = in_size;

    if (in_size >= 0x7fffffff / 4 || out_size < AV_BASE64_SIZE(in_size))
    {
        return NULL;
    }
    ret = dst = out;
    while (bytes_remaining)
    {
        i_bits = (i_bits << 8) + *in++;
        bytes_remaining--;
        i_shift += 8;

        do {
            *dst++ = b64[(i_bits << 6 >> i_shift) & 0x3f];
            i_shift -= 6;
        } while (i_shift > 6 || (bytes_remaining == 0 && i_shift > 0));
    }
    while ((dst - ret) & 3)
        *dst++ = '=';
    *dst = '';

    return ret;
}
void h264_sdp_create(uint8_t *file, uint8_t *ip, uint16_t port,
                     const uint8_t *sps, const int sps_len,
                     const uint8_t *pps, const int pps_len,
                     int payload_type,
                     int time_base,
                     int bitrate)
{
    char buff[1024] = {0};

    char str_profile_level_id[100];
    uint32_t profile_level_id = 0;
    if (sps_len >= 4) { // sanity check
        profile_level_id = sps[1] << 16;
        profile_level_id |= sps[2] << 8;
        profile_level_id |= sps[3];    // profile_idc|constraint_setN_flag|level_idc
    }
    memset(str_profile_level_id, 0, 100);
    sprintf(str_profile_level_id, "%06X", profile_level_id);

    char str_sps[100];
    memset(str_sps, 0, 100);
    av_base64_encode(str_sps, 100, (uint8_t *) sps, sps_len);

    char str_pps[100];
    memset(str_pps, 0, 100);
    av_base64_encode(str_pps, 100, (uint8_t *) pps, pps_len);

    char demo[] =
            "m=video %d RTP/AVP %d
"
            "a=rtpmap:%d H264/%d
"
            "a=fmtp:%d profile-level-id=%06X; packetization-mode=1; sprop-parameter-sets=%s,%s
"
            "c=IN IP4 %s";

    snprintf(buff, sizeof(buff), demo, port, payload_type,
             payload_type, time_base,
             payload_type, profile_level_id, str_sps, str_pps,
             ip);

    printf("h264 sdp:
%s

", buff);
    remove(file);
    FILE *fd = NULL;
    if((fd = fopen(file, "wt")) > 0)
    {
        fwrite(buff, strlen(buff), 1, fd);
        fclose(fd);
    }
}

h264.sdp文件

m=video 9832 RTP/AVP 96
a=rtpmap:96 H264/90000
a=fmtp:96 profile-level-id=640020; packetization-mode=1; sprop-parameter-sets=Z2QAIKzZQMApsBEAAAMAAQAAAwAyDxgxlg==,aOvssiw=
c=IN IP4 10.143.44.169

"m=" video:媒体名称  9832:端口  RTP/AVP:传输协议  96:RTP协议中的pt值

"a=rtpmap":96:RTP协议中的pt值  H264:视频编码  90000:视频采样率

"a=fmtp":

  profile-level-id这个参数用于指示 H.264 流的 profile 类型和级别. 由 Base16(十六进制) 表示的 3 个字节. 第一个字节表示 H.264 的 Profile 类型, 第三个字节表示 H.264 的 Profile 级别

  sprop-parameter-sets:SPS,PPS 这个参数可以用于传输 H.264 的序列参数集和图像参数 NAL 单元. 这个参数的值采用 Base64 进行编码. 不同的参数集间用","号隔开

packetization-mode:表示封包模式:0:单一 NALU 单元模式  1:非交错(non-interleaved)封包模式  2:交错(interleaved)封包模式

Type Packet Unit Single Nal Mode Non-Interleaved Mode Interleaved Mode
0 undefined  ig ig ig
1-23 NAL unit yes yes no
24 STAP-A no yes no
25 STAP-B no no yes
26 MTAP16 no no yes
27 MTAP24 no no yes
28 FU-A no yes yes
29 FU-B no no yes
30-31 undefined  ig ig ig

"c=IN"IP地址

 

 

 

原文地址:https://www.cnblogs.com/vczf/p/13940976.html