因为ios硬解b帧并没有经过重排序,研究了下ijkplayer的处理,在此做个小记录。
硬解后回调如下:
static void VTDecoderCallback(void *decompressionOutputRefCon,
void *sourceFrameRefCon,
OSStatus status,
VTDecodeInfoFlags infoFlags,
CVImageBufferRef imageBuffer,
CMTime presentationTimeStamp,
CMTime presentationDuration)
{
//省略
pthread_mutex_lock(&ctx->m_queue_mutex);
volatile sort_queue *queueWalker = ctx->m_sort_queue;
if (!queueWalker || (newFrame->sort < queueWalker->sort)) { //若队列为空或者newFrame的pts比队列所有的元素都大
newFrame->nextframe = queueWalker;
ctx->m_sort_queue = newFrame;
} else { //找到合适的位置把newframe插进去
bool frameInserted = false;
volatile sort_queue *nextFrame = NULL;
while (!frameInserted) {
nextFrame = queueWalker->nextframe;
if (!nextFrame || (newFrame->sort < nextFrame->sort)) {
newFrame->nextframe = nextFrame;
queueWalker->nextframe = newFrame;
frameInserted = true;
}
queueWalker = nextFrame;
}
}
ctx->m_queue_depth++;
pthread_mutex_unlock(&ctx->m_queue_mutex);
//省略
//当队列的长度大于max_ref_frames时,才可以开始渲染(max_ref_frames由sps解析得到)
if ((ctx->m_queue_depth > ctx->fmt_desc.max_ref_frames)) {
QueuePicture(ctx);
}
}
简单画了个图
其实就是一个按pts大小排序的队列。