原文地址:https://blog.csdn.net/garefield/article/details/45113363
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 --------------------- 作者:garefield 来源:CSDN 原文:https://blog.csdn.net/garefield/article/details/45113363?utm_source=copy 版权声明:本文为博主原创文章,转载请附上博文链接!