ffmpeg播放音频

首先:音频的解码和视频的解码流程是一样的。

1.找到音频流:

 audioStream = -1;
    for (i = 0; i < pFormatCtx->nb_streams; i++) {
        if (pFormatCtx->streams[i]->codec->codec_type == CODEC_TYPE_AUDIO
                && audioStream < 0) {
            audioStream = i;
        }
    }
    if (audioStream == -1)
        return -1;
2.找到音频编解码器:

aCodecCtx=pFormatCtx->streams[audioStream]->codec;

3.需要用到SDL播放音频。这里用到SDL_AudioSpec结构体。

SDL_AudioSpec是包含音频输出格式的结构体:

typedef struct{
  int freq;
  Uint16 format;
  Uint8 channels;
  Uint8 silence;
  Uint16 samples;
  Uint32 size;
  void (*callback)(void *userdata, Uint8 *stream, int len);
  void *userdata;
} SDL_AudioSpec;


int

freq

采样率。可选为11025(11.025KHZ), 22050(22.05KHZ) 和44100(44.1KHZ)。数值越高越好。44.1KHZ是理论上的CD音质界限。

SDL_AudioFormat

format

音频数据格式;format 告诉SDL我们将要给的格式。在“S16SYS”中的S表示有符号的signed,16表示每个样本是16位长的,SYS表示大小头的顺序是与使用的系统相同的。这些格式是由avcodec_decode_audio2为我们给出来的输入音频的格式。

Uint8

channels

声音的通道数 1 单声道, 2 立体声;

Uint8

silence

表示静音的值。因为声音采样是有符号的,所以0当然就是这个值。

Uint16

samples

audio buffer size in samples (power of 2); 详情参考“讨论”

Uint32

size

音频缓存区大小(字节数),当我们想要更多声音的时候,我们想让SDL给出来的声音缓冲区的尺寸。一个比较合适的值在512到8192之间;ffplay使用1024。

SDL_AudioCallback

callback

当音频设备需要更多数据时调用的回调函数; 

void*

userdata

这个是SDL供给回调函数运行的参数。我们将让回调函数得到整个编解码的上下文信息;



















4.打开音频设备:

 if (SDL_OpenAudio(&wanted_spec, &spec) < 0) {
        fprintf(stderr, "SDL_OpenAudio: %s/n", SDL_GetError());
        return -1;
    }
5.avcodec_decode_audio4()解码输出后的音频采样数据格式为AV_SAMPLE_FMT_FLTP,但是SDL能直接识别的格式为AV_SAMPLE_FMT_S16。解决方式是:

int out_linesize;  
//输出内存大小  
int out_buffer_size=av_samples_get_buffer_size(&out_linesize, pCodecCtx->channels,pCodecCtx->frame_size,pCodecCtx->sample_fmt, 1);  
uint8_t *out_buffer=new uint8_t[out_buffer_size];  
...  
au_convert_ctx = swr_alloc();  
au_convert_ctx=swr_alloc_set_opts(au_convert_ctx,AV_CH_LAYOUT_STEREO, AV_SAMPLE_FMT_S16, 44100,  
    pCodecCtx->channel_layout,pCodecCtx->sample_fmt , pCodecCtx->sample_rate,0, NULL);  
swr_init(au_convert_ctx);  
  
while(av_read_frame(pFormatCtx, packet)>=0){  
    ......  
    swr_convert(au_convert_ctx,&out_buffer, out_linesize,(const uint8_t **)pFrame->data , pFrame->nb_samples);  
  
    ......  
}  
可以参考这篇文章:

ffmpeg音频解码


int

freq

采样率

SDL_AudioFormat

format

音频数据格式;format 告诉SDL我们将要给的格式。在“S16SYS”中的S表示有符号的signed,16表示每个样本是16位长的,SYS表示大小头的顺序是与使用的系统相同的。这些格式是由avcodec_decode_audio2为我们给出来的输入音频的格式。

Uint8

channels

声音的通道数 1 单声道, 2 立体声;

Uint8

silence

表示静音的值。因为声音采样是有符号的,所以0当然就是这个值。

Uint16

samples

audio buffer size in samples (power of 2); 详情参考“讨论”

Uint32

size

音频缓存区大小(字节数),当我们想要更多声音的时候,我们想让SDL给出来的声音缓冲区的尺寸。一个比较合适的值在512到8192之间;ffplay使用1024。

SDL_AudioCallback

callback

当音频设备需要更多数据时调用的回调函数; 

void*

userdata

这个是SDL供给回调函数运行的参数。我们将让回调函数得到整个编解码的上下文信息;



你可能感兴趣的:(ffmpeg,sdl)