//在ff_thread_decode_frame中会调用submit_packet将码流交给对应的解码线程,来实现线程状态的改变,具体的流程图见下面图
static int submit_packet(PerThreadContext *p, AVPacket *avpkt)
{
FrameThreadContext *fctx = p->parent;
PerThreadContext *prev_thread = fctx->prev_thread;
const AVCodec *codec = p->avctx->codec;
if (!avpkt->size && !(codec->capabilities & CODEC_CAP_DELAY)) return 0;
pthread_mutex_lock(&p->mutex);
release_delayed_buffers(p);
if (prev_thread) {
int err;
if (prev_thread->state == STATE_SETTING_UP) {
pthread_mutex_lock(&prev_thread->progress_mutex);
while (prev_thread->state == STATE_SETTING_UP) //判断之前的线程状态为STATE_SETTING_UP的时候,进行线程的等待,
pthread_cond_wait(&prev_thread->progress_cond, &prev_thread->progress_mutex);
pthread_mutex_unlock(&prev_thread->progress_mutex);
}
err = update_context_from_thread(p->avctx, prev_thread->avctx, 0);//如果之前的线程状态变为STATE_SETUP_FINISHED,然后从线程中哦功能更新内容
if (err) {
pthread_mutex_unlock(&p->mutex);
return err;
}
}
av_buffer_unref(&p->avpkt.buf);
p->avpkt = *avpkt;
if (avpkt->buf)
p->avpkt.buf = av_buffer_ref(avpkt->buf);
else {
av_fast_malloc(&p->buf, &p->allocated_buf_size, avpkt->size + FF_INPUT_BUFFER_PADDING_SIZE);
p->avpkt.data = p->buf;
memcpy(p->buf, avpkt->data, avpkt->size);
memset(p->buf + avpkt->size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
}
p->state = STATE_SETTING_UP;
pthread_cond_signal(&p->input_cond);//发送码流输入准备好的信号给解码线程pthread_cond_waite(&p->input_cond),让解码线程
pthread_mutex_unlock(&p->mutex);
/*
* If the client doesn't have a thread-safe get_buffer(),
* then decoding threads call back to the main thread,
* and it calls back to the client here.
*/
if (!p->avctx->thread_safe_callbacks && (
#if FF_API_GET_BUFFER
p->avctx->get_buffer ||
#endif
p->avctx->get_buffer2 != avcodec_default_get_buffer2)) {
while (p->state != STATE_SETUP_FINISHED && p->state != STATE_INPUT_READY) {
pthread_mutex_lock(&p->progress_mutex);
while (p->state == STATE_SETTING_UP)
pthread_cond_wait(&p->progress_cond, &p->progress_mutex);
if (p->state == STATE_GET_BUFFER) {
p->result = ff_get_buffer(p->avctx, p->requested_frame, p->requested_flags);
p->state = STATE_SETTING_UP;
pthread_cond_signal(&p->progress_cond);
}
pthread_mutex_unlock(&p->progress_mutex);
}
}
fctx->prev_thread = p;
fctx->next_decoding++;
return 0;
}
主线程接收数据,准备完毕后发出pthread_cond_signal(&p->input_cond)信号,然后解码线程接收到以后,设置线程状态为finish_setup,发送广播p->process_cond,进行解码,
解码线程解完以后,发送p->progress_cond信号,主线程回调,从解码线程中获取get_buffer,解码之后的数据,然后发送p->progress_cond信号给解码线程,然后解码线程发出p->output_cond信号给主线程,主线程输出解码之后的frame给用户
注释1: