FFMPEG中关于rtmp的研究

来源:互联网 发布:易语言取中间文本源码 编辑:程序博客网 时间:2024/05/18 02:26

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)
0 0
原创粉丝点击