ffmpeg+sdl2.0做一个简单的音频播放器

阅读: 评论:0

ffmpeg+sdl2.0做一个简单的音频播放器

ffmpeg+sdl2.0做一个简单的音频播放器

困扰我有一段日子的这个东东今晚终于搞好了。

先声明一下,我用的ffmpeg的版本是ffmpeg-20140227-git-b5005de

版本升级以后,跟以前主要的区别是ffmpeg对音频解码后的帧格式不再是AV_SAMPLE_FMT_S16了,跟视频一样,多了平面格式

枚举类型AVSampleFormat声明于libavutil/samplefmt.h中,如下:

/*** Audio Sample Formats** @par* The data described by the sample format is always in native-endian order.* Sample values can be expressed by native C types, hence the lack of a signed* 24-bit sample format even though it is a common raw audio data format.** @par* The floating-point formats are based on full volume being in the range* [-1.0, 1.0]. Any values outside this range are beyond full volume level.** @par* The data layout as used in av_samples_fill_arrays() and elsewhere in FFmpeg* (such as AVFrame in libavcodec) is as follows:** For planar sample formats, each audio channel is in a separate data plane,* and linesize is the buffer size, in bytes, for a single plane. All data* planes must be the same size. For packed sample formats, only the first data* plane is used, and samples for each channel are interleaved. In this case,* linesize is the buffer size, in bytes, for the 1 plane.*/
enum AVSampleFormat {AV_SAMPLE_FMT_NONE = -1,AV_SAMPLE_FMT_U8,          ///< unsigned 8 bitsAV_SAMPLE_FMT_S16,         ///< signed 16 bitsAV_SAMPLE_FMT_S32,         ///< signed 32 bitsAV_SAMPLE_FMT_FLT,         ///< floatAV_SAMPLE_FMT_DBL,         ///< doubleAV_SAMPLE_FMT_U8P,         ///< unsigned 8 bits, planarAV_SAMPLE_FMT_S16P,        ///< signed 16 bits, planarAV_SAMPLE_FMT_S32P,        ///< signed 32 bits, planarAV_SAMPLE_FMT_FLTP,        ///< float, planarAV_SAMPLE_FMT_DBLP,        ///< double, planarAV_SAMPLE_FMT_NB           ///< Number of sample formats. DO NOT USE if linking dynamically
};

所以要对解码后的音频进行重采样,ffmpeg的源码里面附有一个简单的音频重采样的例子——resampling_audio.c:产生一个简单的sin tone进行重采样,参考此源码以及网上另一位大神的代码( ),下面给出我重写以后的例子:

#include "stdafx.h"#include <iostream>
using namespace std;#include <stdio.h>
#include <tchar.h>#include <io.h>
#include <direct.h>
extern "C"
{
#include "libavutil/opt.h"
#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"
#include "libswscale/swscale.h"
#include "libswresample/swresample.h"
#include "SDL.h"
#include "SDL_thread.h"
};#pragma warning(disable: 4996)#pragma comment(lib,"avutil.lib")
#pragma comment(lib,"avcodec.lib")
#pragma comment(lib,"avformat.lib")
#pragma comment(lib,"swscale.lib")
#pragma comment(lib,"swresample.lib")#pragma comment(lib,"sdl2.lib")#define NB_SAMPLE 1152//这里如果是播放aac要改成1024//全局变量---------------------
static  Uint8  *audio_chunk;
static  Uint32  audio_len;
static  Uint8  *audio_pos;int AudioResampling(AVCodecContext * audio_dec_ctx,AVFrame * pAudioDecodeFrame,int out_sample_fmt,int out_channels,int out_sample_rate)
{SwrContext * swr_ctx = NULL;int data_size = 0;int ret = 0;int64_t src_ch_layout = audio_dec_ctx->channel_layout;int64_t dst_ch_layout = AV_CH_LAYOUT_STEREO;int dst_nb_channels = 0;int dst_linesize = 0;int src_nb_samples = 0;int dst_nb_samples = 0;int max_dst_nb_samples = 0;uint8_t **dst_data = NULL;int resampled_data_size = 0;swr_ctx = swr_alloc();if (!swr_ctx){printf("swr_alloc error n");return -1;}src_ch_layout = (audio_dec_ctx->channels ==av_get_channel_layout_nb_channels(audio_dec_ctx->channel_layout)) ?audio_dec_ctx->channel_layout :av_get_default_channel_layout(audio_dec_ctx->channels);if (out_channels == 1){dst_ch_layout = AV_CH_LAYOUT_MONO;printf("dst_ch_layout: AV_CH_LAYOUT_MONOn");}else if (out_channels == 2){dst_ch_layout = AV_CH_LAYOUT_STEREO;printf("dst_ch_layout: AV_CH_LAYOUT_STEREOn");}else{dst_ch_layout = AV_CH_LAYOUT_SURROUND;printf("dst_ch_layout: AV_CH_LAYOUT_SURROUNDn");}if (src_ch_layout <= 0){printf("src_ch_layout error n");return -1;}src_nb_samples = pAudioDecodeFrame->nb_samples;if (src_nb_samples <= 0){printf("src_nb_samples error n");return -1;}av_opt_set_int(swr_ctx, "in_channel_layout", src_ch_layout, 0);av_opt_set_int(swr_ctx, "in_sample_rate", audio_dec_ctx->sample_rate, 0);av_opt_set_sample_fmt(swr_ctx, "in_sample_fmt", audio_dec_ctx->sample_fmt, 0);av_opt_set_int(swr_ctx, "out_channel_layout", dst_ch_layout, 0);av_opt_set_int(swr_ctx, "out_sample_rate", out_sample_rate, 0);av_opt_set_sample_fmt(swr_ctx, "out_sample_fmt", (AVSampleFormat)out_sample_fmt, 0);if ((ret = swr_init(swr_ctx)) < 0) {printf("Failed to initialize the resampling contextn");return -1;}max_dst_nb_samples = dst_nb_samples = av_rescale_rnd(src_nb_samples, out_sample_rate, audio_dec_ctx->sample_rate, AV_ROUND_UP);if (max_dst_nb_samples <= 0){printf("av_rescale_rnd error n");return -1;}dst_nb_channels = av_get_channel_layout_nb_channels(dst_ch_layout);ret = av_samples_alloc_array_and_samples(&dst_data, &dst_linesize, dst_nb_channels,dst_nb_samples, (AVSampleFormat)out_sample_fmt, 0);if (ret < 0){printf("av_samples_alloc_array_and_samples error n");return -1;}dst_nb_samples = av_rescale_rnd(swr_get_delay(swr_ctx, audio_dec_ctx->sample_rate) +src_nb_samples, out_sample_rate, audio_dec_ctx->sample_rate, AV_ROUND_UP);if (dst_nb_samples <= 0){printf("av_rescale_rnd error n");return -1;}if (dst_nb_samples > max_dst_nb_samples){av_free(dst_data[0]);ret = av_samples_alloc(dst_data, &dst_linesize, dst_nb_channels,dst_nb_samples, (AVSampleFormat)out_sample_fmt, 1);max_dst_nb_samples = dst_nb_samples;}if (swr_ctx){ret = swr_convert(swr_ctx, dst_data, dst_nb_samples,(const uint8_t **)pAudioDecodeFrame->data, pAudioDecodeFrame->nb_samples

本文发布于:2024-01-31 19:39:18,感谢您对本站的认可!

本文链接:https://www.4u4v.net/it/170670115830888.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

留言与评论(共有 0 条评论)
   
验证码:

Copyright ©2019-2022 Comsenz Inc.Powered by ©

网站地图1 网站地图2 网站地图3 网站地图4 网站地图5 网站地图6 网站地图7 网站地图8 网站地图9 网站地图10 网站地图11 网站地图12 网站地图13 网站地图14 网站地图15 网站地图16 网站地图17 网站地图18 网站地图19 网站地图20 网站地图21 网站地图22/a> 网站地图23