ffmpeg修改源码添加flv对pcm的打包支持

flv支持的音频包含pcm_mulaw和 pcm_alaw 但使用ffmpeg打包输出的文件使用解码器打开发现无法真确得到音频的格式信息,分析源码发现除了AAC、H264、MPEG4之外,其余的格式信息未被写入到流中,修改flvenc.c,找到flv_write_header函数,在函数最后写格式信息部分修改如下:
    for (i = 0; i < s->nb_streams; i++) {
        AVCodecContext *enc = s->streams[i]->codec;
        if (enc->codec_id == AV_CODEC_ID_AAC
            || enc->codec_id == AV_CODEC_ID_H264
            || enc->codec_id == AV_CODEC_ID_MPEG4
             || enc->codec_id == AV_CODEC_ID_PCM_MULAW
            || enc->codec_id == AV_CODEC_ID_PCM_ALAW
            ) {
            int64_t pos;
            avio_w8(pb, enc->codec_type == AVMEDIA_TYPE_VIDEO ?
                    FLV_TAG_TYPE_VIDEO : FLV_TAG_TYPE_AUDIO);
            avio_wb24(pb, 0); // size patched later
            avio_wb24(pb, 0); // ts
            avio_w8(pb, 0);   // ts ext
            avio_wb24(pb, 0); // streamid
            pos = avio_tell(pb);
            if (enc->codec_id == AV_CODEC_ID_AAC
                 || enc->codec_id == AV_CODEC_ID_PCM_MULAW
                || enc->codec_id == AV_CODEC_ID_PCM_ALAW) {
                avio_w8(pb, get_audio_flags(s, enc));
                avio_w8(pb, 0); // AAC sequence header
                avio_write(pb, enc->extradata, enc->extradata_size);
            } else {
                avio_w8(pb, enc->codec_tag | FLV_FRAME_KEY); // flags
                avio_w8(pb, 0); // AVC sequence header
                avio_wb24(pb, 0); // composition time
                ff_isom_write_avcc(pb, enc->extradata, enc->extradata_size);
            }
            data_size = avio_tell(pb) - pos;
            avio_seek(pb, -data_size - 10, SEEK_CUR);
            avio_wb24(pb, data_size);
            avio_skip(pb, data_size + 10 - 3);
            avio_wb32(pb, data_size + 11); // previous tag size
        }
    }
红色部分为添加的内容
添加此部分内容后,输出的文件解码器可以得到音频信息,但读不出音频数据,跟踪后发现音频数据没有被写入,猜测与在转换时dts被重置有关,查了下有AV_NOPTS_VALUE这个变量,强制将stream的cur_dts和pkt的dts置为此常量,声音就有了

你可能感兴趣的:(音视频)