今天遇到个应用在S2机器上拖动播放随机花屏的问题,其他机子都没有。那么如何分析花屏问题呢,我这里主要分析点播和本地文件播放导致的花屏,并不涉及直播花屏分析?
分析花屏问题无外乎从解复用->解码->显示这三步开始排查。(好吧,这个花屏问题真的让人蛋疼啊)
1.排查是否显示问题
先从显示开始排查,可以直接把解码后的数据编码成图片然后取出来,如果取出来的图片是花屏的,那么就继续往解码以及解复用开始排查。如果取出来的图片不是花屏的,那么就可以判断为显示导致的花屏。
先看下在jik中对解码后的帧编码图片取到本地的实现方式:
我们需要先获取到软解码后的帧数据,在ff_ffplay的ffplay_video_thread函数中,这里直接取。
int i = 0;//作为编码成图片的帧序列号,函数外
...
...
for (;;) {
//软解码获取到解码后的视频帧
ret = get_video_frame(ffp, frame);
if (ret < 0)
goto the_end;
if (!ret)
continue;
//add by hxk,花屏检测的实现方式
#if 0
AVFrame *pFrameRGB;
pFrameRGB = av_frame_alloc();//申请内存
if(pFrameRGB == NULL) {
av_log(NULL, AV_LOG_ERROR, "pFrameRGB malloc failed!\n");
return;
}
int numBytes = avpicture_get_size(AV_PIX_FMT_RGB24, is->viddec.avctx->width, is->viddec.avctx->height);
uint8_t * buffer = (uint8_t *)av_malloc(numBytes * sizeof(uint8_t));
avpicture_fill((AVPicture*)pFrameRGB, buffer, AV_PIX_FMT_RGB24, is->viddec.avctx->width, is->viddec.avctx->height);
struct SwsContext* img_convert_ctx;
img_convert_ctx = sws_getContext(is->viddec.avctx->width,is->viddec.avctx->height, frame->format,
is->viddec.avctx->width, is->viddec.avctx->height, AV_PIX_FMT_RGB24, SWS_BICUBIC, NULL, NULL, NULL);
sws_scale(img_convert_ctx, (const uint8_t * const *)frame->data, (const int *)frame->linesize, 0, is->viddec.avctx->height,
pFrameRGB->data, pFrameRGB->linesize);
SaveFrame(pFrameRGB, is->viddec.avctx->width, is->viddec.avctx->height, i++);
av_free(buffer);
av_free(pFrameRGB);
sws_freeContext(img_conv