FFmepg 多线程解码历程 - 7:submit_packet
来源:互联网 发布:音频发射器软件 编辑:程序博客网 时间:2024/05/29 19:09
//在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:
- FFmepg 多线程解码历程 - 7:submit_packet
- FFmepg 多线程解码历程 - 7:submit_packet
- FFmepg 多线程解码历程
- FFmepg 多线程解码历程
- FFmepg 多线程解码历程 - 1:validate_thread_parameters
- FFmepg 多线程解码历程 - 2 :avcodec_decode_video2
- FFmepg 多线程解码历程 - 3: int ff_thread_decode_frame
- FFmepg 多线程解码历程 - 4:avcodec_open2
- FFmepg 多线程解码历程 - 5: ff_thread_init
- FFmepg 多线程解码历程 - 6:frame_thread_init
- FFmepg 多线程解码历程 - 1:validate_thread_parameters
- FFmepg 多线程解码历程 - 2 :avcodec_decode_video2
- FFmepg 多线程解码历程 - 3: int ff_thread_decode_frame
- FFmepg 多线程解码历程 - 4:avcodec_open2
- FFmepg 多线程解码历程 - 5: ff_thread_init
- FFmepg 多线程解码历程 - 6:frame_thread_init
- ffmepg开发历程
- FFMEPG avs2 解码支持
- ASP.NET 记事本
- 【Linux】Linux下配置jdk环境变量的几种方法
- Allegro带通孔焊盘的制作,相关尺寸设置
- 摄像机线数与IPC的分辨率区别
- iframe 跨协议访问
- FFmepg 多线程解码历程 - 7:submit_packet
- 长假后上了两天班
- 服务器数据库系列 - NoSQL架构实践
- 转:c语言中的字符数组与字符串
- hdu 2048 神、上帝以及老天爷
- 游戏编程精粹
- Java中的继承与多态
- Android中对Log日志文件的分析
- 调用Service中的方法