zoukankan      html  css  js  c++  java
  • 生成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地址

     

     

     

  • 相关阅读:
    ListActivity优点
    博客随笔
    第三周作业附加题之课外书读后感
    第3周作业。
    第三周作业
    读《弟弟》,笔记
    使用git将文件上传到Coding
    第二周作业
    第一周作业
    第零次作业
  • 原文地址:https://www.cnblogs.com/vczf/p/13940976.html
Copyright © 2011-2022 走看看