本篇说一下解码线程。
在stream_component_open函数中,分别创建了一个视频解码线程和音频解码线程:
static int stream_component_open(VideoState *is, int stream_index)
{
...
switch (avctx->codec_type) {
case AVMEDIA_TYPE_AUDIO:
...
if ((ret = decoder_start(&is->auddec, audio_thread, is)) < 0)
goto out;
break;
case AVMEDIA_TYPE_VIDEO:
...
if ((ret = decoder_start(&is->viddec, video_thread, is)) < 0)
goto out;
break;
default:
break;
}
goto out;
fail:
avcodec_free_context(&avctx);
out:
av_dict_free(&opts);
return ret;
}
对函数做了一些简化,在调用decoder_start函数时,创建了音频解码线程audio_thread和视频解码线程video_thread。
由于audio_thread和video_thread的内容差不多,所以以下仅分析一下audio_thread:
static int audio_thread(void *arg)
{
VideoState *is = arg;
AVFrame *frame = av_frame_alloc();
Frame *af;
int got_frame = 0;
AVRational tb;
int ret = 0;
if (!frame)
return AVERROR(ENOMEM);
do {
if ((got_frame = decoder_decode_frame(&is->auddec, frame, NULL)) < 0)
goto the_end;
if (got_frame) {
tb = (AVRational){1, frame->sample_rate};
if (!(af = frame_queue_peek_writable(&is->sampq)))
goto the_end;