zoukankan      html  css  js  c++  java
  • FFmpeg编程学习笔记二:音频重採样


          ffmpeg实现音频重採样的核心函数swr_convert功能很强大,但是ffmpeg文档对它的凝视太过简单。在应用中往往会出这样那样的问题,事实上在读取数据->重採样->编码数据的循环中在第一次运行swr_convert后还应用swr_convert再作个缓存检測看看是否还有数据。假设有就要把它写到FIFO中去,留在下次再使用,这点在转码和由低向高转换採样率时特别重要。

         以下一段简单的代码,摘自我自已写的測试程序.


    	const int frame_size = FFMIN(fifo_size, m_Opt->encode_pCodecCtx->frame_size);
    
    
    	if ((ret = av_audio_fifo_read(m_fifo, (void **)m_fifo_samples_array, frame_size)) < frame_size) {
    		fprintf(stderr, "Could not read data from FIFO
    ");
    		return AVERROR_EXIT;
    	}
    
    	int out_samples = av_rescale_rnd(swr_get_delay(m_Opt->out_resample_context, 48000) + 1536, 44100, 48000, AV_ROUND_UP);
    
    
    	int conver_samples= swr_convert(m_Opt->out_resample_context, m_fifo_conver_samples_array, frame_size,
    		(const uint8_t **)m_fifo_samples_array, frame_size);
    	ret = av_audio_fifo_size(m_conver_fifo);
    
    	if ((ret = av_audio_fifo_realloc(m_conver_fifo, av_audio_fifo_size(m_conver_fifo) + frame_size)) < 0) {
    			fprintf(stderr, "Could not reallocate FIFO
    ");
    			return ret;
    		}
    
    	ret = av_audio_fifo_write(m_conver_fifo, (void **)m_fifo_conver_samples_array, conver_samples);
    		fifo_size = av_audio_fifo_size(m_conver_fifo);
    
    		if ((ret = av_audio_fifo_read(m_conver_fifo, (void **)m_Opt->out_samples_array, frame_size)) < frame_size) {
    			fprintf(stderr, "Could not read data from FIFO
    ");
    			return AVERROR_EXIT;
    		}
    		
    		ret = Encode_audio(ret);
    
    		int ret1 = 0;
    
    		while ((ret1 = swr_convert(m_Opt->out_resample_context, m_fifo_conver_samples_array, frame_size, NULL, 0)) > 0)
    	{
    	
    
    		if ((ret = av_audio_fifo_realloc(m_conver_fifo, av_audio_fifo_size(m_conver_fifo) + ret1)) < 0) {
    			fprintf(stderr, "Could not reallocate FIFO
    ");
    			return ret;
    		}
    
    		ret = av_audio_fifo_write(m_conver_fifo, (void **)m_fifo_conver_samples_array, ret1);
    		fifo_size = av_audio_fifo_size(m_conver_fifo);
    
    		if (fifo_size > m_Opt->encode_pFrame->nb_samples)
    		{
    
    			if ((ret = av_audio_fifo_read(m_conver_fifo, (void **)m_Opt->out_samples_array, frame_size)) < frame_size) {
    				fprintf(stderr, "Could not read data from FIFO
    ");
    				return AVERROR_EXIT;
    			}
    
    			ret = Encode_audio(ret);
    
    		}

    由于是測试代码,有点乱中间也有一些不必要的步骤。主要是为了调试好用。

    重点在:

        if ((r = swr_convert(swr_ctx, output, output_nb_samples,(const uint8_t**)input, nb_samples)) < 0)
            return -1;
    
        while ((r = swr_convert(swr_ctx, output, output_nb_samples, NULL, 0)) > 0) {
     
        }



  • 相关阅读:
    Window PHP 使用命令行模式
    LNMP ftp 可以登录无权限操作?
    linux 允许mysql用户远程访问
    解决报错:scandir() has been disabled for security reasons
    LNMP 配置二级域名
    MUI 图片上传剪切预览,可选(拍照+系统相册)
    MUI 单个图片上传预览(拍照+系统相册):先选择->预览->上传提交
    MUI 单图片压缩上传(拍照+系统相册): 选择立即上传
    循环递归的区别?
    如何让自己的广播只让指定的 app 接收?
  • 原文地址:https://www.cnblogs.com/mengfanrong/p/5418662.html
Copyright © 2011-2022 走看看