ffmpeg添加MP4的pcm音频支持

来源:互联网 发布:淘宝客怎么推广宝贝 编辑:程序博客网 时间:2024/04/28 12:23
   ffmpeg中对MP4的打包处理是在movenc.c中,在实际打包过程中发现除了mov类型外,其它类型如vob等均无法生成音频的声道信息,经过分析发现在mov_write_audio_tag函数的最后有如下代码
 if (track->mode == MODE_MOV && track->enc->codec_type == AVMEDIA_TYPE_AUDIO)
        mov_write_chan_tag(pb, track);
即只有MP4为mov类型的时候才会写入音频信息,因此这个判断需要修改为
 if ( track->enc->codec_type == AVMEDIA_TYPE_AUDIO)
        mov_write_chan_tag(pb, track);
即不论哪种MP4,均将声道信息写入。
为MP4编码添加pcm音频支持:
static const AVCodecTag codec_ipod_tags[] = {
    { AV_CODEC_ID_H264,     MKTAG('a','v','c','1') },
    { AV_CODEC_ID_MPEG4,    MKTAG('m','p','4','v') },
    { AV_CODEC_ID_AAC,      MKTAG('m','p','4','a') },
    { AV_CODEC_ID_PCM_MULAW,MKTAG('u','l','a','w') },
    { AV_CODEC_ID_PCM_ALAW, MKTAG('a','l','a','w') },
    { AV_CODEC_ID_ALAC,     MKTAG('a','l','a','c') },
    { AV_CODEC_ID_AC3,      MKTAG('a','c','-','3') },
    { AV_CODEC_ID_MOV_TEXT, MKTAG('t','x','3','g') },
    { AV_CODEC_ID_MOV_TEXT, MKTAG('t','e','x','t') },
    { AV_CODEC_ID_NONE, 0 },
};

static const AVCodecTag codec_3gp_tags[] = {
    { AV_CODEC_ID_H263,     MKTAG('s','2','6','3') },
    { AV_CODEC_ID_H264,     MKTAG('a','v','c','1') },
    { AV_CODEC_ID_MPEG4,    MKTAG('m','p','4','v') },
    { AV_CODEC_ID_AAC,      MKTAG('m','p','4','a') },
    { AV_CODEC_ID_PCM_MULAW,MKTAG('u','l','a','w') },
    { AV_CODEC_ID_PCM_ALAW, MKTAG('a','l','a','w') },
    { AV_CODEC_ID_AMR_NB,   MKTAG('s','a','m','r') },
    { AV_CODEC_ID_AMR_WB,   MKTAG('s','a','w','b') },
    { AV_CODEC_ID_MOV_TEXT, MKTAG('t','x','3','g') },
    { AV_CODEC_ID_NONE, 0 },
};

static const AVCodecTag codec_f4v_tags[] = { // XXX: add GIF/PNG/JPEG?
    { AV_CODEC_ID_MP3,    MKTAG('.','m','p','3') },
    { AV_CODEC_ID_AAC,    MKTAG('m','p','4','a') },
    { AV_CODEC_ID_PCM_MULAW,MKTAG('u','l','a','w') },
    { AV_CODEC_ID_PCM_ALAW,MKTAG('a','l','a','w') },
    { AV_CODEC_ID_H264,   MKTAG('a','v','c','1') },
    { AV_CODEC_ID_VP6A,   MKTAG('V','P','6','A') },
    { AV_CODEC_ID_VP6F,   MKTAG('V','P','6','F') },
    { AV_CODEC_ID_NONE, 0 },
};
以上红色部分是添加的针对pcm的格式信息,然后在mov_write_header函数中,还需要设置声道信息,将
 else if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
            track->timescale = st->codec->sample_rate;
改为
else if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
            if (st->codec->codec_id == AV_CODEC_ID_PCM_MULAW || st->codec->codec_id == AV_CODEC_ID_PCM_ALAW)
            {
                st->codec->channels = 1;
                st->codec->sample_rate = 8000;
                st->codec->channel_layout = AV_CH_LAYOUT_MONO;
                st->codec->sample_fmt = AV_SAMPLE_FMT_S16;
                track->enc->channels = 1;
                track->enc->channel_layout = AV_CH_LAYOUT_MONO;
            }
            track->timescale = st->codec->sample_rate;
红色部分是添加内容

此外,解码部分也要做修改,在mov_chan.c中,添加
static const enum MovChannelLayoutTag mov_ch_layouts_law[] = {
    MOV_CH_LAYOUT_MONO,
    MOV_CH_LAYOUT_STEREO,
    0,
};
以及修改mov_codec_ch_layouts的定义为
static const struct {
    enum AVCodecID codec_id;
    const enum MovChannelLayoutTag *layouts;
} mov_codec_ch_layouts[] = {
    { AV_CODEC_ID_AAC,     mov_ch_layouts_aac      },
    { AV_CODEC_ID_PCM_MULAW, mov_ch_layouts_law    },
    { AV_CODEC_ID_PCM_ALAW,  mov_ch_layouts_law    },
    { AV_CODEC_ID_AC3,     mov_ch_layouts_ac3      },
    { AV_CODEC_ID_ALAC,    mov_ch_layouts_alac     },
    { AV_CODEC_ID_PCM_U8,    mov_ch_layouts_wav    },
    { AV_CODEC_ID_PCM_S8,    mov_ch_layouts_wav    },
    { AV_CODEC_ID_PCM_S16LE, mov_ch_layouts_wav    },
    { AV_CODEC_ID_PCM_S16BE, mov_ch_layouts_wav    },
    { AV_CODEC_ID_PCM_S24LE, mov_ch_layouts_wav    },
    { AV_CODEC_ID_PCM_S24BE, mov_ch_layouts_wav    },
    { AV_CODEC_ID_PCM_S32LE, mov_ch_layouts_wav    },
    { AV_CODEC_ID_PCM_S32BE, mov_ch_layouts_wav    },
    { AV_CODEC_ID_PCM_F32LE, mov_ch_layouts_wav    },
    { AV_CODEC_ID_PCM_F32BE, mov_ch_layouts_wav    },
    { AV_CODEC_ID_PCM_F64LE, mov_ch_layouts_wav    },
    { AV_CODEC_ID_PCM_F64BE, mov_ch_layouts_wav    },
    { AV_CODEC_ID_NONE,    NULL                    },
};
这两部分内容是定义pam的声道模式,然后还要修改isom.c
在ff_mp4_obj_type中添加
    { AV_CODEC_ID_PCM_MULAW   , 0xE3 }, /* a private definition */
    { AV_CODEC_ID_PCM_ALAW  , 0xE4 }, /* a private definition */
这两个定义是pcm的流类型标志定义,参考自另一个MP4打包库mpeg4ip的MP4.h

0 0
原创粉丝点击