ijkplayer阅读笔记06-音频流程
来源:互联网 发布:摄影网络销售 编辑:程序博客网 时间:2024/05/18 00:05
本节主要介绍音频从读取,到解码,再到播放的流程:
读取音视频数据(文件或流) --> 创建播放线程 --> 创建解码线程 --> 循环读取音频包 --> 推送到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); } }}
0 0
- ijkplayer阅读笔记06-音频流程
- ijkplayer阅读笔记07-视频流程
- ijkplayer阅读笔记04-音频解码线程详解
- ijkplayer阅读学习笔记之从代码上看播放流程
- ijkplayer阅读学习笔记之从代码上看播放流程
- ijkplayer阅读笔记01-初始化操作
- ijkplayer阅读笔记03-视频解码线程详解
- ijkplayer阅读笔记05-视频显示线程详解
- ijkplayer阅读学习笔记之ijk源代码获取
- ijkplayer 笔记
- ijkplayer整理笔记(二)——ffplayer流程解析
- 音频开发ijkplayer小结 android
- ijkplayer的实现流程
- ijkPlayer编译流程记录
- IJKPlayer简单实用流程
- webrtc音频引擎源码阅读笔记
- IjkPlayer 源码阅读一 初始化
- ijkplayer阅读笔记02-创建音视频读取,解码,播放线程
- Oracle SQL Developer远程连接服务器端oracle数据库配置。
- 泛型的用法
- 234Palindrome Linked List
- 求解立方根
- 解决Win UAC问题的编程
- ijkplayer阅读笔记06-音频流程
- Linux移植相关链接
- Java中线程总结
- snapper命令技巧
- jquery中获取动态checkbox是否被选中
- Android Volley完全解析(二),使用Volley加载网络图片
- window下编译lua源码,编译lua的库文件,编译lua解释器,编译lua编译器
- Extjs实现角色权限流控制,对fieldset,checkbox的动态控制
- 天声人語