ffmpeg多线程解码流程
2016-01-19 11:21
253 查看
FFMPEG多线程编码器一般以在Slice内分功能模块进行多线程编码,如h263,h263P,msmpeg(v1, v2, v3),wmv1。包含以下几个线程:(1)Pre_estimation_motion_thread运动估计前的准备;(2)Estimation_motion_thread运动估计;(3)Mb_var_thread宏块其他变量;(4)Encode_thread编码主线程。当然也有例外,如FFV1编码器按Slice为线程单位进行多线程编码。
FFMPEG多线程解码器分为Frame级和Slice级两种,Slice级多线程同时解码一帧中不同的部分。Frame级多线程同时接受多帧码流,实现并行解码,当前帧处于显示状态时,未来的几帧已经在其他线程中被解码。
Slice Threading
FFmpeg中,dvvideo_decoder, ffv1_decoder, h264_decoder, mpeg2_video_decoder和mpeg_video_decoder均支持了Slice Threading。
实现方法是:首先为codecContext注册注册多线程处理函数excute(),Codec解码过程中处理Slice时调用avctx->excute()。excute()启动Slice解码工作线程开始多线程解码,同时快速返回开始下一Slice的解析和解码。
Frame Threading主线程和解码线程的同步如图1所示。
图1 Frame Threading主线程和解码线程的同步
Frame Threading
目前为止支持Frame Threading的解码器有h264_decoder, huffyuv_decoder, ffvhuff_decoder, mdec_decoder, mimic_decoder, mpeg4_decoder, theora_decoder, vp3_decoder和vp8_decoder。
Frame Threading有如下限制:用户函数draw_horiz_band()必须是线程安全的;为了提升性能,用户应该为codec提供线程安全的get_buffer()回调函数;用户必须能处理多线程带来的延时。另外,支持Frame Threading的codec要求每个包包含一个完整帧。Buffer内容在ff_thread_await_progress()调用之前不能读,同样,包括加边draw_edges()在内的处理,在ff_thread_report_progress()调用之后,Buffer内容不能写。
每个线程都有以下四个状态。如图2所示,为了保证线程安全,若Codec未实现update_thread_context()和线程安全的get_buffer(),则必须在解码完成后才能将状态转换为STATUS_SETUP_FINISHED,意味着下一个线程只能在当前线程解码完成后才能开始解码。
而如图3所示,如果Codec实现update_thread_context()和线程安全的get_buffer(),线程状态可以在解码开始之前转换为STATUS_SETUP_FINISHED,这样,下一个线程就可能与当前线程并行。
图2 Codec未实现update_thread_context()和线程安全的get_buffer(),线程状态转换
图3 Codec实现update_thread_context()和线程安全的get_buffer(),线程状态转换
解码主线程通过调用submit_packet()将码流交给对应的解码线程。主线程和解码线程的同步如图4所示。
图4 Frame Threading主线程和解码线程的同步
FFMPEG多线程解码器分为Frame级和Slice级两种,Slice级多线程同时解码一帧中不同的部分。Frame级多线程同时接受多帧码流,实现并行解码,当前帧处于显示状态时,未来的几帧已经在其他线程中被解码。
Slice Threading
FFmpeg中,dvvideo_decoder, ffv1_decoder, h264_decoder, mpeg2_video_decoder和mpeg_video_decoder均支持了Slice Threading。
实现方法是:首先为codecContext注册注册多线程处理函数excute(),Codec解码过程中处理Slice时调用avctx->excute()。excute()启动Slice解码工作线程开始多线程解码,同时快速返回开始下一Slice的解析和解码。
Frame Threading主线程和解码线程的同步如图1所示。
图1 Frame Threading主线程和解码线程的同步
Frame Threading
目前为止支持Frame Threading的解码器有h264_decoder, huffyuv_decoder, ffvhuff_decoder, mdec_decoder, mimic_decoder, mpeg4_decoder, theora_decoder, vp3_decoder和vp8_decoder。
Frame Threading有如下限制:用户函数draw_horiz_band()必须是线程安全的;为了提升性能,用户应该为codec提供线程安全的get_buffer()回调函数;用户必须能处理多线程带来的延时。另外,支持Frame Threading的codec要求每个包包含一个完整帧。Buffer内容在ff_thread_await_progress()调用之前不能读,同样,包括加边draw_edges()在内的处理,在ff_thread_report_progress()调用之后,Buffer内容不能写。
每个线程都有以下四个状态。如图2所示,为了保证线程安全,若Codec未实现update_thread_context()和线程安全的get_buffer(),则必须在解码完成后才能将状态转换为STATUS_SETUP_FINISHED,意味着下一个线程只能在当前线程解码完成后才能开始解码。
而如图3所示,如果Codec实现update_thread_context()和线程安全的get_buffer(),线程状态可以在解码开始之前转换为STATUS_SETUP_FINISHED,这样,下一个线程就可能与当前线程并行。
图2 Codec未实现update_thread_context()和线程安全的get_buffer(),线程状态转换
图3 Codec实现update_thread_context()和线程安全的get_buffer(),线程状态转换
解码主线程通过调用submit_packet()将码流交给对应的解码线程。主线程和解码线程的同步如图4所示。
图4 Frame Threading主线程和解码线程的同步
相关文章推荐
- 自动获取代理
- Linux学习之路——分区的知识点
- sql 中 order by
- 拦截PHP各种异常和错误,发生致命错误时进行报警,万事防患于未然
- 关于ABAP事件的一张图
- PHP盛宴——经常使用函数集锦
- 个人网址使用收藏
- 新春特惠,全场7折
- Linux SSH 失败问题
- Mybatis拦截器介绍及分页插件
- Android 手机拍照预览图像与拍照图像
- Java注解(3)-源码级框架
- Hadoop生态上几个技术的关系与区别:hive、pig、hbase 关系与区别
- $(function(){})与window.onload=function(){}的区别
- 2015年12月16日 Oracle语句实现有则更新无则插入
- 动态获取UIWebView的真正高度
- DBCP、C3P0、Proxool 、 BoneCP开源连接池的比《转》
- 测试工作——XPath
- Windows 8.1升级至Windows 10后,启动VisualSVN Server Manager报错:提供程序无法执行所尝试的操作 (0x80041024)的解决
- 友元