想利用cocoa自带的硬解VDT框架,去解码h24视频,省去ffmpeg软件带来的发热耗电问题。
调研中遇到的坑
- 寻找图像参数集pps及序列参数集sps,用于解码。
ffmpeg中上述信息保存在AVcodecContext的extradata中,要从上述字段中自己找出相应的pps sps得以保存。uint8_t *extraData = pCodecCtx->extradata; int extraSize = pCodecCtx->extradata_size; for(unsigned int i = 0; i < extraSize; ++i) { if ((i > 0) && extraData[i] == 0x67) { int lengthPos = i -1; _spsSize = extraData[lengthPos]; _sps = malloc(_spsSize); memcpy(_sps, extraData + i, _spsSize); } if (extraData[i] == 0x68) { int lengthPos = i -1; _ppsSize = extraData[lengthPos]; _pps = malloc(_ppsSize); memcpy(_pps, extraData + i, _ppsSize); } }
如果是标准的264流,在读取每个naul根据头信息判断是否为sps pps
* 解码后B,P帧重排问题
VDT解码是按照dts的顺序解的,在有B帧的情况下,解出来的数据的pts是乱序的,如果即可交给渲染器渲染,会出现常见的抖动现象。ffmpeg中Avpacket中保留有pts和dts信息,利用pts对解码之后的数据进行重排序之后进行渲染,可以消除抖动问题
* 音画同步问题
视频流根据pts和时基算出时间,和全局时钟对比保证音画同步。
* demo地址 :https://github.com/duoluo/WFHardDecodeDemo
* demo中包含的问题:没有添加opengl相应的渲染代码,只是利用NSImageView渲染了每一帧。