在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为空时,音频播放线程会阻塞,这时候需要唤醒该线程。