[FFMPEG]协议:rtmp一些说明

1.ffmpeg推送rtmp流时,要求将音视频封装为flv格式,对音视频的编码格式都有要求:

关于flv还会单独开辟一篇文章进行详细分析
<1>视频支持格式如下:

{ AV_CODEC_ID_FLV1,     FLV_CODECID_H263 },
{ AV_CODEC_ID_H263,     FLV_CODECID_REALH263 },
{ AV_CODEC_ID_MPEG4,    FLV_CODECID_MPEG4 },
{ AV_CODEC_ID_FLASHSV,  FLV_CODECID_SCREEN },
{ AV_CODEC_ID_FLASHSV2, FLV_CODECID_SCREEN2 },
{ AV_CODEC_ID_VP6F,     FLV_CODECID_VP6 },
{ AV_CODEC_ID_VP6,      FLV_CODECID_VP6 },
{ AV_CODEC_ID_VP6A,     FLV_CODECID_VP6A },
{ AV_CODEC_ID_H264,     FLV_CODECID_H264 },
{ AV_CODEC_ID_NONE,     0 }

<2>音频支持格式如下:

{ AV_CODEC_ID_MP3 },
{ AV_CODEC_ID_PCM_U8},
{ AV_CODEC_ID_PCM_S16BE },
{ AV_CODEC_ID_PCM_S16LE },
{ AV_CODEC_ID_ADPCM_SWF },
{ AV_CODEC_ID_AAC},
{ AV_CODEC_ID_NELLYMOSER },
{ AV_CODEC_ID_PCM_MULAW },
{ AV_CODEC_ID_PCM_ALAW},
{ AV_CODEC_ID_SPEEX},
{ AV_CODEC_ID_NONE,       0 }

目前主流大多采用h.264+aac的编码组合

2.ffmpeg可提供flvflags选项以配置FLV头的额外数据,设置后AAC音频可支持除44100, 22050, 11025以外的采样率;

原理:该问题主要是利用了aac的扩展字节来实现的;

{ "flvflags", "FLV muxer flags", offsetof(FLVContext, flags), AV_OPT_TYPE_FLAGS, {.i64 = 0}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "flvflags" },
原代码如下:
if (!enc->extradata_size && flv->flags & 1) {
    PutBitContext pbc;
    int samplerate_index;
    int channels = flv->audio_enc->channels - (flv->audio_enc->channels == 8 ? 1 : 0);
    uint8_t data[2];
    for (samplerate_index = 0; samplerate_index < 16; samplerate_index++)
        if (flv->audio_enc->sample_rate == mpeg4audio_sample_rates[samplerate_index])
           break;
    init_put_bits(&pbc, data, sizeof(data));
    put_bits(&pbc, 5, flv->audio_enc->profile + 1); //profile
    put_bits(&pbc, 4, samplerate_index); //sample rate index
    put_bits(&pbc, 4, channels);
    put_bits(&pbc, 1, 0); //frame length - 1024 samples
    put_bits(&pbc, 1, 0); //does not depend on core coder
    put_bits(&pbc, 1, 0); //is not extension
    flush_put_bits(&pbc);

    avio_w8(pb, data[0]);
    avio_w8(pb, data[1]);
    av_log(s, AV_LOG_WARNING, "AAC sequence header: %02x %02x.\n", data[0], data[1]);
}
 avio_write(pb, enc->extradata, enc->extradata_size);

3.将TS(H.264+AAC)的流重新封装为FLV时,需要丢掉AAC的ADTS HEADER

flv_muxer的源码如下:

if (enc->codec_id == AV_CODEC_ID_AAC && pkt->size > 2 &&(AV_RB16(pkt->data) & 0xfff0) == 0xfff0) {    //音频为AAC,且存在ADTS的同步头syncword
        if (!s->streams[pkt->stream_index]->nb_frames) {
            av_log(s, AV_LOG_ERROR, "Malformed AAC bitstream detected: "
                       "use the audio bitstream filter 'aac_adtstoasc' to fix it "
                       "('-bsf:a aac_adtstoasc' option with ffmpeg)\n");
            return AVERROR_INVALIDDATA;
        }
        av_log(s, AV_LOG_WARNING, "aac bitstream error\n");
    }

|ADTS AAC数据格式|

 |--------------------------------------------------------------------------|
 |ADTS_header |    AAC ES | ADTS_header | AAC ES | ... | ADTS_header | AAC ES  |
 |--------------------------------------------------------------------------|
 
     |ADTS_header adts_fixed_header数据格式|
         |
         |--syncword[12]:同步头,值固定为0xFFF,表示一个ADTS帧的开始;
         |--ID[1]:MPEG版本。(0:MPEG-4,1:MPEG-2;
         |--Layer[2]:always: '00'
         |--protection_absent[1]
         |--profile[2]:表示使用哪个级别的AAC,有些芯片只支持AAC LC 。在MPEG-2 AAC中定义了3种:0-main profile;1-Low Complexity profile(LC);2-Scalable Sampling Rate profile(SSR);3-reserved
         |--sampling_frequency_index[4]:表示使用的采样率下标,通过这个下标在 Sampling Frequencies[ ]数组中查找得知采样率的值;
         There are 13 supported frequencies:
                0: 96000 Hz    1: 88200 Hz    2: 64000 Hz    3: 48000 Hz    4: 44100 Hz    5: 32000 Hz
                6: 24000 Hz    7: 22050 Hz    8: 16000 Hz    9: 12000 Hz    10: 11025 Hz    11: 8000 Hz
                12: 7350 Hz    13: Reserved    14: Reserved    15: frequency is written explictly
         |--private_bit[1]
         |--channel_configuration[3]: 表示声道数 
            0: Defined in AOT Specifc Config
            1: 1 channel: front-center
            2: 2 channels: front-left, front-right
            3: 3 channels: front-center, front-left, front-right
            4: 4 channels: front-center, front-left, front-right, back-center
            5: 5 channels: front-center, front-left, front-right, back-left, back-right
            6: 6 channels: front-center, front-left, front-right, back-left, back-right, LFE-channel
            7: 8 channels: front-center, front-left, front-right, side-left, side-right, back-left, back-right, LFE-channel
           8-15: Reserved
         |--original_copy[1]
         |--home[1]
    |ADTS_header adts_variable_header数据格式|
         |--copyright_identification_bit
         |--copyright_identification_start
         |--aac_frame_length: 一个ADTS帧的长度包括ADTS头和AAC原始流;
         |--adts_buffer_fullness:0x7FF 说明是码率可变的码流;
         |--number_of_raw_data_blocks_in_frame

4.ffmpeg关于rtmp的实现:

<1>借助第三方库librtmp(librtmp.c);
<2>自己实现的rtmp接口(rtmpproto.c)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

酷咪哥

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值