在ijkplayer 读线程中提到,函数stream_component_open()中的decoder_start()会创建音频解码线程,来看解码线程audio_thread()的主要代码
static int audio_thread(void *arg)
{
...
do {
...
if ((got_frame = decoder_decode_frame(ffp, &is->auddec, frame, NULL)) < 0)
goto the_end;
if (got_frame) {
...
if (!(af = frame_queue_peek_writable(&is->sampq)))
goto the_end;
...
av_frame_move_ref(af->frame, frame);
frame_queue_push(&is->sampq);
...
}
} while (ret >= 0 || ret == AVERROR(EAGAIN) || ret == AVERROR_EOF);
...
}
能看到音频解码线程是这样工作的,首先调用decoder_decode_frame()函数进行音频帧解码,然后调用frame_queue_peek_writable()判断sampq是否能写,av_frame_move_ref()将解码后的音频帧放入sampq相应位置(放入位置为frame_queue_peek_writable给出的返回值af),最后调用frame_queue_push(),这个函数用来唤醒线程,当sampq为空时,音频播放线程会阻塞,这时候需要唤醒该线程。