视频遇到的错误
1、设置帧率
video_st->time_base.num = 1;
video_st->time_base.den = 25;
如果还不管用:
AVDictionary* opt = NULL;
av_dict_set(&opt, "video_track_timescale", "25", 0);
if (avformat_write_header(oc,&opt)<0)
{
fprintf(stderr, "Could not write header for output file\n");
exit(1);
}
2、提示错误 //[mp4 @ 02d07fe0] Codec for stream 0 does not use global headers but container format requires global header
解决方法:
//oVcc->flags = CODEC_FLAG_GLOBAL_HEADER;
if(oc->oformat->flags & AVFMT_GLOBALHEADER)
oVcc->flags |= CODEC_FLAG_GLOBAL_HEADER;
3、h264需要设置的参数
oVcc->qmin = 10;
oVcc->qmax = 51;
//设置参数
AVDictionary *param = 0;
if (oVcc->codec_id == AV_CODEC_ID_H264)
{
av_dict_set(¶m, "preset", "superfast",0);
av_dict_set(¶m, "tune", "zerolatency",0);
}
oVc = avcodec_find_encoder(oVcc->codec_id); //AV_CODEC_ID_H264
if (!oVc){
printf("can't find suitable videoencoder\n");
exit(0);
}
ret = avcodec_open2(oVcc, oVc, ¶m);
if (ret < 0){
printf("can't open the output video codec\n");
exit(0);
}
4、需要转换pix_fmt
struct SwsContext *img_convert_ctx;
img_convert_ctx = sws_getContext(vCodecCtx->width, vCodecCtx->height, vCodecCtx->pix_fmt,
oVcc->width, oVcc->height, oVcc->pix_fmt, SWS_BICUBIC, NULL, NULL, NULL);
音频错误:
1、需要设置 sample_fmt, 否则解码提示 -22
audio_st->codec->sample_fmt = AV_SAMPLE_FMT_S16; //解码失败 -22 -------------------------------------------
2、
//av_get_channel_layout_nb_channels(channel_layout);
//av_get_default_channel_layout(pCodecCtx->channels);
oAcc->channels = aCodecCtx->channels;
oAcc->channel_layout = aCodecCtx->channel_layout;
3、需要每帧视频的采样数不同 ,mp3 是1152
int samplesPerFrame = 1024;
if (oAcc->codec_id == AV_CODEC_ID_AAC){
samplesPerFrame = 1024;
}
else if(oAcc->codec_id == AV_CODEC_ID_MP3){
samplesPerFrame = 1152;
}
4、需要转换
struct SwrContext *au_convert_ctx;
au_convert_ctx = swr_alloc();
au_convert_ctx=swr_alloc_set_opts(au_convert_ctx,oAcc->channel_layout, audio_st->codec->sample_fmt, oAcc->sample_rate,
aCodecCtx->channel_layout,aCodecCtx->sample_fmt , aCodecCtx->sample_rate,0, NULL);
swr_init(au_convert_ctx);
//解码得到的数据类型为float 4bit,而播放器播放的格式一般为S16(signed 16bit),就需要对解码得到的数据进行转换
/data转 extended_data //里面存放着 指向数据的指针,下面的红位置
int len = swr_convert(au_convert_ctx,&out_buffer_audio, MAX_AUDIO_FRAME_SIZE,(const uint8_t **)oAFrame->extended_data , oAFrame->nb_samples);
5、1152--》1024 解码出来的AVFrame中的nb_samples 太多,encode 成AAC的时候,会出现 more samples to frame
需要用到 AVAudioFifo 接口