HEVC的测试代码HM中给出了一个解码器示例,但是该解码器只能输出结果到yuv文件,不能跟放电影一样阅览。所以离实际应用总有一定距离,我现在刚开始学习HEVC,也想深入了解HEVC的编解码原理和具体过程,所以创建了这样一个播放器。该播放器和以前所做的一个基于ffmpeg的播放器基本框架几乎完全一样,所不同的是解码环节。
下面我们开始着手分析构建这样一个真实的播放器的流程。
一、基本流程分析
最简单的,一个播放器应该具有的基本功能是让用户选择一个文件并且播放,暂时不支持复杂的功能的问题是考虑到界面设计带来的问题(能力有限就要集中能力做主要的事情嘛)。
要想播放视频,首先必须要得到视频的每一帧图像。怎么得到一帧一帧的图像呢,我们可以借助于HM的示例代码予以分析。
我们启动和调试TAppDecoder项目,该项目中演示了一个HEVC解码器所做的基本工作。界面显示应该归于应用程序,而不是我们的解码器,所以HM中没有考虑。示例程序的解码流程如图 1所示。
1 解码器的流程图
我们需要做的工作就是,把原来解码器的解码结果输出到文件(依赖于程序的运行参数),修改成把解码的每一帧图像送给我们的应用程序,由应用程序显示每一帧图像。
稍微细致地走一遍代码,设置断点并且跟踪执行,发现了一个重要突破点,在于TAppDecoder::decode函数的末尾部分,有一个函数调用,即xWriteOutput(字面意思是写入输出,解码器要输出什么,当然是解码的结果,yuv图像啦),该函数的调用表明了一帧图像的读取完毕,程序尝试把该帧图像写入到文件。
知道这点之后,我们的工作便大致有了方向,便是修改该函数(函数框架也需要修改),改成在这里做更新界面的操作。
二、一帧图像的获取
自己再细致地阅读一下这个 TAppDecTop::xWriteOutput函数的内容,发现后来在while循环中有这么一句话。
m_cTVideoIOYuvReconFile.write( pcPic->getPicYuvRec(),
crop.getPicCropLeftOffset(), crop.getPicCropRightOffset(),
crop.getPicCropTopOffset(), crop.getPicCropBottomOffset() );
<