基於ffmpeg-0.10 SDK的音訊重取樣
阿新 • • 發佈:2018-10-31
這個示例程式碼實現了基於FFmpeg-0.10 SDK的音訊重取樣,也可用於實現定點轉浮點計算。
1. 宣告
/* ffmpeg_sdk.h */ #include <stdio.h> #include <stdlib.h> #ifdef __cplusplus extern "C" { #endif #include "libavutil/imgutils.h" #include "libavutil/opt.h" #include "libavcodec/avcodec.h" #include "libavutil/mathematics.h" /* open log */ #include "libavutil/log.h" /* audio resample */ #include "libswresample/swresample.h" /* end */ #ifdef __cplusplus } #endif class FFmpegSDK{ public: FFmpegSDK(); ~FFmpegSDK(); #define INPUT_AUDIO_CHANNEL_LAYOUT AV_CH_LAYOUT_MONO #define INPUT_AUDIO_SAMPLE_FMT AV_SAMPLE_FMT_S16 #define INPUT_AUDIO_SAMPLE_RATE 16000 private: SwrContext *m_swrctx; public: int32_t init_swresample(int32_t in_audio_channel_layout, enum AVSampleFormat in_audio_sample_fmt, int32_t in_audio_sample_rate); int32_t destroy_swrsample(); int32_t swresample_doing(uint8_t** out_sample_buf, int32_t out_sample_cnt, const uint8_t** in_sample_buf, int32_t in_sample_cnt); }; }
2. 定義
/* ffmpeg_sdk.cpp */ int32_t FFmpegSDK::init_swresample(int32_t in_audio_channel_layout, enum AVSampleFormat in_audio_sample_fmt, int32_t in_audio_sample_rate){ m_swrctx = swr_alloc(); if (m_swrctx == NULL){ ERROR_LOG("Allocate swresample failed!\n"); return -1; } #if LIBSWRESAMPLE_VERSION_MINOR >= 17 // #else m_swrctx = swr_alloc_set_opts(m_swrctx, m_avctx->channel_layout, m_avctx->sample_fmt, m_avctx->sample_rate, in_audio_channel_layout, in_audio_sample_fmt, in_audio_sample_rate, 0, NULL); #endif int32_t ret = swr_init(m_swrctx); if (ret < 0){ ERROR_LOG("swr_init(->) failed!\n"); return -1; } return 0; } int32_t FFmpegSDK::destroy_swrsample(){ return 0; } int32_t FFmpegSDK::swresample_doing(uint8_t** out_sample_buf, int32_t out_sample_cnt, const uint8_t** in_sample_buf, int32_t in_sample_cnt){ int32_t len = 0; len = swr_convert(m_swrctx, out_sample_buf, out_sample_cnt, in_sample_buf, in_sample_cnt); if (len < 0){ char errmsg[1024]; av_strerror(len, errmsg, sizeof(errmsg)); ERROR_LOG("swr_convert!(%d)(%s)", len, errmsg); return len; } return 0; }
3. 呼叫
int FFmpegSDK::init(){ ret = init_swresample(INPUT_AUDIO_CHANNEL_LAYOUT, INPUT_AUDIO_SAMPLE_FMT, INPUT_AUDIO_SAMPLE_RATE); if (ret < 0){ ERROR_LOG("init swresample failed!"); return false; } 。。。 } int FFmpegSDK::run(){ AVCodecContext *m_avctx; 。。。 m_avctx->channel_layout = AV_CH_LAYOUT_MONO; m_avctx->sample_fmt = AV_SAMPLE_FMT_FLT; m_avctx->sample_rate = 16000; float *out_buf= new float[1024]; memset(out_buf, 0, 1024 * sizeof(float)); 。。。 ret = swresample_doing((uint8_t**)&out_buf, 1024, (const uint8_t**)&in_buf, 1024); 。。。 }