ffmpeg 内存读写封装遇到的问题

最近在做ffmpeg接口封装,遇到一些问题,简单分享下;后续将代码分析后再上传分享

1、flv封装:flv封装不支持16000采样率,需要重采样,才能进一步封装

2、音频重采样需要经过解码->重采样->编码;每一步中对每一帧数据都需要使用同一个Context

3、avi封装:avi封装,25帧,视频时间基为1/600,则duration为24,但是封装后avi文件中的duration=1;导致文件无法在android中播放,所以修改时间基1/50.使得duration=1有效,可以播放

	// 设置avi格式的时间基;原有时间基1/600,在android中无法播放
	// avi封装后解析出来的duration都等于1,通过修改时间基,使得duration等于1可以正常解析
	if (p_output->format == FFMPEG_MUXER_AVI)
	{
		p_output->stream[V_INDEX]->time_base.num = 1;
		p_output->stream[V_INDEX]->time_base.den = 50;
	}

3、内存读写中的读函数返回值注意,返回-1,代表已经封装结束,不能再进行读数据了

4、打开输入流时,需要指定音频或视频数据

	// 不设置in_fmt或默认都是视频输入,音频读写一百多字节的数据导致报到文件尾的错误
	in_fmt = av_find_input_format(format);
	if (NULL == in_fmt)
	{
		ALOGE("%s[%d]:av_find_input_format %s failed\n", __FUNCTION__, __LINE__, format);
		goto err;
	}

	if ((ret = avformat_open_input(&p_input_info->fmt_ctx, NULL, in_fmt, NULL)) < 0)
	{
		ALOGE("%s[%d]:avformat_open_input failed ret=%d\n", __FUNCTION__, __LINE__, ret);
		goto err;
	}

5、aac编码需要添加头aac音频流的头,否则无法在android上播放,保存在extradata中

	//添加aac音频流的头;不添加无法在安卓上播放
	if (p_output->audio.encType == AV_CODEC_ID_AAC)
	{
		make_dsi( (unsigned int)get_sr_index( (unsigned int)p_output->audio.sample_rate),\
					(unsigned int)p_output->audio.channels, p_output->audio_extradata);
		p_output->stream[A_INDEX]->codecpar->extradata = p_output->audio_extradata;
		p_output->stream[A_INDEX]->codecpar->extradata_size = 2;
	}

6、h264编码需要添加sps等信息,否则无法在android上播放,保存在extradata中

// 判断是I帧,再进行保存,
flag = (*(p_data_buf+4)&0x1F);
if (flag == 0x05 || flag == 0x07 || flag == 0x08)
{
	memcpy(p_muxer_info->output.video_extradata, p_data_buf, 32);
	p_muxer_info->output.stream[V_INDEX]->codecpar->extradata = p_muxer_info->output.video_extradata;
	p_muxer_info->output.stream[V_INDEX]->codecpar->extradata_size = 32;
}

7、aac编码,封装每一帧时需要过滤掉aac音频帧前面的头

  //aac音频数据需要过滤
if (p_muxer_info->output.audio.encType ==  AV_CODEC_ID_AAC)
{
	p_muxer_info->input_a.bsfc = av_bitstream_filter_init("aac_adtstoasc");
	if (p_muxer_info->input_a.bsfc == NULL)
	{
		ALOGE("%s[%d]:av_bitstream_filter_init  failed\n", __FUNCTION__, __LINE__);
		return -1;
	}
}


// 分离某些格式
if (p_muxer_info->output.audio.encType ==  AV_CODEC_ID_AAC)
{
		ret = av_bitstream_filter_filter(p_muxer_info->input_a.bsfc, p_muxer_info->input_a.stream->codec,NULL, &pkt->data, &pkt->size, pkt->data, pkt->size, 0);
		if (ret < 0)
		{
			ALOGE("%s[%d]:av_bitstream_filter_filter failed ret = %d\n", __FUNCTION__, __LINE__, ret);
			return -1;
		}
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值