H264进行推流时往往需要首先发送AVC Sequence Header,也就是AVCDecoderConfigurationRecor结构,其格式定义如下:

avc-file-format.jpg

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
// 解析出sps,pps
bool ParseAVCConfigurationRecord(const uint8_t *data, int len) {
    const uint8_t *ptr = data;
    const uint8_t *ptr_end = data + len;
    int sps_length = 0, pps_length = 0;
    int num_sps = 0, num_pps = 0;
    int i;
    const uint8_t *sps = nullptr, *pps = nullptr;

    if (len < 8) {
        return false;
    }
    // sps
    num_sps = ptr[5] & 0x1f;
    assert(num_sps == 1); // should only one
    ptr += 6;
    for (i = 0; i < num_sps; i++) {
        sps_length = ReadBigEndian16(ptr);
        if (ptr + sps_length + 2 > ptr_end) {
            assert("invalid sps, parse AVConfigurationRecord failed." && false);
            return false;
        }
        sps = ptr + 2;
        ptr += (sps_length + 2);
    }
    assert(ptr < ptr_end);

    // pps
    num_pps = ptr[0] & 0x1f;
    assert(num_pps == 1);
    ++ptr;
    for (i = 0; i < num_pps; i++) {
        pps_length = ReadBigEndian16(ptr);
        if (ptr + pps_length + 2 > ptr_end) {
            assert("invalid pps, parse AVConfigurationRecord failed." && false);
            return false;
        }
        pps = ptr + 2;
        ptr += (pps_length + 2);
    }
}

使用FFMpeg rtmp拉流时,AVCDecoderConfigurationRecord保存在video AVCodecContext extradata数组下,所以解析sps/pps时调用 ParseAVCConfigurationRecord(_video_dec_ctx->extradata, _video_dec_ctx->extradata_size).