说明:
HEVC解码并行分3个级别:frame并行,slice并行和wpp。FFmpeg默认提供frame并行和slice并行的框架。针对HEVC,FFmpeg实现的帧内并行是wpp。
1)关于thread_type,也就是并行模式,其实分两种:slice并行和fram+slice并行(注意这句话:Frame thread:Restrictions with slice threading also apply)。所以openHEVC在frame thread init中也会slice thread init;优先判断frame thread;参数命名上,也是默认参数 for slice,特别注明的才是 for frame。
2)FFmpeg中并行解码部分稍显混乱,264与265共用了部分上层框架,但264的并行解码又有若干问题,间接影响了265。
3)openHEVC的并行解码代码就清晰不少,FFMpeg中并行解码部分大概同步到openHEVC 2013年10月提交,后面可能因为框架原因,没有再同步。
1 validate_thread_parameters
设置active_thread_type 对应并行级别
/**
* Set the threading algorithms used.
*
* Threading requires more than one thread.
* Frame threading requires entire frames to be passed to the codec,
* and introduces extra decoding delay, so is incompatible with low_delay.
*
* @param avctx The context.
*/
static void validate_thread_parameters(AVCodecContext *avctx)
{
//! 帧级并行支持标记
int frame_threading_supported = (avctx->codec->capabilities & AV_CODEC_CAP_FRAME_THREADS)
&& !(avctx->flags & AV_CODEC_FLAG_TRUNCATED)
&& !(avctx->flags & AV_CODEC_FLAG_LOW_DELAY)
&& !(avctx->flags2 & AV_CODEC_FLAG2_CHUNKS);
if (avctx->thread_count == 1) { ///< 多核支持
avctx->active_thread_type = 0;
} else if (frame_threading_supported && (avctx->thread_type & FF_THREAD_FRAME)) { ///< codec设置
avctx->active_thread_type = FF_THREAD_FRAME;
} else if (avctx->codec->capabilities & AV_CODEC_CAP_SLICE_THREADS &&
avctx->thread_type & FF_THREAD_SLICE) { ///< slice级并行
avctx->active_thread_type = FF_THREAD_SLICE;
} else if (!(avctx->codec->capabilities & AV_CODEC_CAP_AUTO_THREADS)) {
avctx->thread_count = 1;
avctx->active_thread_type = 0;
} ///< auto 已设置
if (avctx->thread_count > MAX_AUTO_THREADS)
av_log(avctx, AV_LOG_WARNING,
"Application has requested %d threads. Using a thread count greater than %d is not recommended.\n",
avctx->thread_count, MAX_AUTO_THREADS);
}
.capabilities := AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY | AV_CODEC_CAP_SLICE_THREADS | AV_CODEC_CAP_FRAME_THREADS
12322 = 1<< 1 | 1<< 5 | 1<< 13 | 1<< 12
2
3<