您的位置:首页 > 其它

ijkplayer阅读笔记06-音频流程

2015-08-17 11:03 127 查看
本节主要介绍音频从读取,到解码,再到播放的流程:

读取音视频数据(文件或流) --> 创建播放线程 --> 创建解码线程 --> 循环读取音频包 --> 推送到is->audioq ---> audio_thread从audioq获取音频包解码并推送到sampq --> aout_thread 从 sampq获取解码好的音频帧,推送到AudioTrack播放

音频解码流程:从文件或流中读取音频包,推送到is->audioq队列中

1)读取线程
read_thread{
avformat_open_input
avformat_find_stream_info
for (i = 0; i < ic->nb_streams; i++) {
AVStream *st = ic->streams[i];
enum AVMediaType type = st->codec->codec_type;
st_index[type] = i;
}
st_index[AVMEDIA_TYPE_AUDIO] = av_find_best_stream(ic, AVMEDIA_TYPE_AUDIO,
st_index[AVMEDIA_TYPE_AUDIO],
st_index[AVMEDIA_TYPE_VIDEO],
NULL, 0);

if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
ret = stream_component_open(ffp, st_index[AVMEDIA_TYPE_VIDEO]);{
Vid eoState *is = ffp->is;
AVFormatContext *ic = is->ic;
AVCodecContext *avctx;
AVCodec *codec;
avctx = ic->streams[stream_index]->codec;
codec = avcodec_find_decoder(avctx->codec_id);
audio_open(ffp, channel_layout, nb_channels, sample_rate, &is->audio_tgt);{
wanted_spec.callback = sdl_audio_callback;
wanted_spec.userdata = opaque;
SDL_AoutOpenAudio(ffp->aout, &wanted_spec, &spec){
aout->open_audio(aout, desired, obtained);{
aout_open_audio_n{
// aout_thread 线程从解码好的音频帧队列sampq中,循环取数据推入AudioTrack中播放
SDL_CreateThreadEx(&opaque->_audio_tid, aout_thread);{
}
}
}
}
}
is->audio_stream = stream_index;
is->audio_st = ic->streams[stream_index];
is->audio_tid = SDL_CreateThreadEx(&is->_audio_tid, audio_thread, ffp, "ff_audio_dec"); //创建音频解码线程,从audioq队列中获取音频包,解码并加入sampq音频帧列表中
}
}

for (;;) {
ret = av_read_frame(ic, pkt);
packet_queue_put(&is->audioq, pkt);  //读取音频帧,推送到音频帧队列is->aidopq中
}
}

2)音频解码线程:从is->audioq中获取音频包解码,推送到音频解码帧列表is->sampq中
audio_thread{
do {
decoder_decode_frame(ffp, &is->auddec, frame, NULL){
packet_queue_get_or_buffering(ffp, d->queue, &pkt)
avcodec_decode_audio4
}
af = frame_queue_peek_writable(&is->sampq)
av_frame_move_ref(af->frame, frame);
frame_queue_push(&is->sampq);
}
}

3)音频播放线程:从音频解码帧列表中is->sampq获取解码帧,推送到AudioTrack播放
aout_thread{
aout_thread_n{
while (!opaque->abort_request) {
audio_cblk(userdata, buffer, copy_size);{
sdl_audio_callback(void *opaque, Uint8 *stream, int len){
while (len > 0) {
audio_size = audio_decode_frame(ffp);{
af = frame_queue_peek_readable(&is->sampq)
is->audio_buf = af->frame->data[0];
}
memcpy(stream, (uint8_t *)is->audio_buf+is->audio_buf_index, len1);
}
}
}
SDL_Android_AudioTrack_write_byte(env, atrack, buffer, copy_size);
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: