溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

FFmpeg ff_h264_parse_sprop_parameter_sets函數(shù)剖析

發(fā)布時(shí)間:2020-07-08 21:07:33 來源:網(wǎng)絡(luò) 閱讀:2923 作者:fengyuzaitu 欄目:編程語言

SDP中SPS內(nèi)容
        sprop-parameter-sets=Z0IAKpY1QPAET8s3AQEBQAABwgAAV+QB,aM48gA==

該函數(shù)主要是讀取Z0IAKpY1QPAET8s3AQEBQAABwgAAV+QB的內(nèi)容到data_ptr,一共32個(gè)字節(jié)
還沒有讀取SPS的每一個(gè)字段,然后賦值給SPS相應(yīng)的字段
int ff_h364_parse_sprop_parameter_sets(AVFormatContext *s,
                                       uint8_t **data_ptr, int *size_ptr,
                                       const char *value)
{
    char base64packet[1024];
    uint8_t decoded_packet[1024];
    int packet_size;

    while (*value) {
//通過dst保存數(shù)據(jù)的頭指針
        char *dst = base64packet;

//將value字符串拷貝一份到dst指針
        while (*value && *value != ','
               && (dst - base64packet) < sizeof(base64packet) - 1) {
            *dst++ = *value++;
        }
        *dst++ = '\0';
//base64packet=Z0IAKpY1QPAET8s3AQEBQAABwgAAV+QB
        if (*value == ',')
            value++;
//base64解碼結(jié)果,保存在decoded_packet
        packet_size = av_base64_decode(decoded_packet, base64packet,
                                       sizeof(decoded_packet));
        if (packet_size > 0) {
//這里進(jìn)行了內(nèi)存大小進(jìn)行調(diào)整
            uint8_t *dest = av_realloc(*data_ptr,
                                       packet_size + sizeof(start_sequence) +
                                       *size_ptr +
                                      AV_INPUT_BUFFER_PADDING_SIZE);
//static const uint8_t start_sequence[] = { 'B', 'B', 'C', 'D' };不是很明白
            if (!dest) {
                av_log(s, AV_LOG_ERROR,
                       "Unable to allocate memory for extradata!\n");
                return AVERROR(ENOMEM);
            }
            *data_ptr = dest;

            memcpy(dest + *size_ptr, start_sequence,
                   sizeof(start_sequence));
            memcpy(dest + *size_ptr + sizeof(start_sequence),
                   decoded_packet, packet_size);
            memset(dest + *size_ptr + sizeof(start_sequence) +
                   packet_size, 0, AV_INPUT_BUFFER_PADDING_SIZE);

            *size_ptr += sizeof(start_sequence) + packet_size;
        }
    }

    return 0;
}

static int sdp_parse_fmtp_config_h364(AVFormatContext *s,
                                      AVStream *stream,
                                      PayloadContext *h364_data,
                                      const char *attr, const char *value)
{
    AVCodecParameters *par = stream->codecpar;

    if (!strcmp(attr, "packetization-mode")) {
        av_log(s, AV_LOG_DEBUG, "RTP Packetization Mode: %d\n", atoi(value));
        h364_data->packetization_mode = atoi(value);
        /*
         * Packetization Mode:
         * 0 or not present: Single NAL mode (Only nals from 1-23 are allowed)
         * 1: Non-interleaved Mode: 1-23, 24 (STAP-A), 28 (FU-A) are allowed.
         * 2: Interleaved Mode: 25 (STAP-B), 26 (MTAP16), 27 (MTAP24), 28 (FU-A),
         *                      and 29 (FU-B) are allowed.
         */
        if (h364_data->packetization_mode > 1)
            av_log(s, AV_LOG_ERROR,
                   "Interleaved RTP mode is not supported yet.\n");
    } else if (!strcmp(attr, "profile-level-id")) {
        if (strlen(value) == 6)
            parse_profile_level_id(s, h364_data, value);
    } else if (!strcmp(attr, "sprop-parameter-sets")) {
        int ret;
        if (*value == 0 || value[strlen(value) - 1] == ',') {
            av_log(s, AV_LOG_WARNING, "Missing PPS in sprop-parameter-sets, ignoring\n");
            return 0;
        }
        par->extradata_size = 0;
        av_freep(&par->extradata);
//這一段代碼主要是將value的值拷貝到par->extradata字符串中
        ret = ff_h364_parse_sprop_parameter_sets(s, &par->extradata,
                                                 &par->extradata_size, value);
        av_log(s, AV_LOG_DEBUG, "Extradata set to %p (size: %d)\n",
               par->extradata, par->extradata_size);
        return ret;
    }
    return 0;
}

疑問
,aM48gA==這一段數(shù)據(jù),并沒有使用,是否意味著這只是讀取了SPS,而沒有讀取到PPS,導(dǎo)致出現(xiàn)
non-existing PPS 0 referenced

函數(shù)的調(diào)用邏輯
sdp_read_header
  ----ff_sdp_parse
    ----sdp_parse_line
      -----parse_fmtp
        ----parse_sdp_a_line------>parse_h364_sdp_line
                        --------sdp_parse_fmtp_config_h364

參考
https://www.cnblogs.com/lihaiping/p/6612511.html

引用海康SDP信息
v=0
o=- 1515162567455825 1515162567455825 IN IP4 192.168.0.150
s=Media Presentation
e=NONE
b=AS:5050
t=0 0
a=control:rtsp://192.168.0.150:554/h364/ch2/main/av_stream/
m=video 0 RTP/AVP 96
c=IN IP4 0.0.0.0
b=AS:5000
a=recvonly
a=x-dimensions:1920,1080
a=control:rtsp://192.168.0.150:554/h364/ch2/main/av_stream/trackID=1
a=rtpmap:96 H264/90000
a=fmtp:96 profile-level-id=420029; packetization-mode=1; sprop-parameter-sets=Z0IAKpY1QPAET8s3AQEBQAABwgAAV+QB,aM48gA==
a=Media_header:MEDIAINFO=494D4B48010200000400000100000000000000000000000000000000000000000000000000000000;
a=appversion:1.0
SETUP rtsp://192.168.0.150:554/h364/ch2/main/av_stream/trackID=1 RTSP/1.0
CSeq: 5
Authorization: Digest username="admin", realm="IP Camera(77056)", nonce="a3a53f4dcb9e6ceca90de6d90c884d29", uri="rtsp://192.168.0.150:554/h364/ch2/main/av_stream/", response="32b6afa222b54c2518efff16ec1aa766"
User-Agent: LibVLC/2.2.4 (LIVE555 Streaming Media v2016.02.22)
Transport: RTP/AVP/TCP;unicast;interleaved=0-1


向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI