正在做硬件编码成h264流形成mp4文件项目。
我遇到的问题封装的mp4视频无法用常用播放软件打开,在html网页上也无法播放。在微信默认播放器和vlc,在ubuntu上也能正常播放。打印编码后的h264视频流数据,发现存在两个00 00 00 01 Head。一个AUD Nal Unit type,另外一个IDR或者P帧。
把编码数据写入mp4v2容器//nalu数据
unsigned char* pNalu;
//nalu类型
unsigned char naluType;
//nalu数据长度
int len;
//获取nalu类型
naluType = pNalu[0] & 0x1F;
bool isIdr = true;
//上一帧时间戳
int64_t timestamp=0;
//naluType :1-5都是视频帧,其中5是idr。
switch (naluType)
{
case 01:
case 02:
case 03:
case 04:
isIdr = false;
case 05://idr
//mp4 sample的nalu前面需要加上四位需要记录长度
pNalu -= 4;
pNalu[0] = (len >> 24) & 0xFF;
pNalu[1] = (len >> 16) & 0xFF;
pNalu[2] = (len >> 8) & 0xFF;
pNalu[3] = (len >> 0) & 0xFF;
auto _duration = frame.timestamp - timestamp;
timestamp = frame.timestamp;
MP4WriteSample(pHandle, videoId, pNalu, len + 4, duration * timeScale / 1000, 0, isIdr);
break;
}
这样写进去数据的视频就出现我一开始提及的,一般播放无法播放。
经过N次尝试,还是无法成功。偶然发现编码器初始化参数
vpuencodetype=NX_AVC_ENC ;
hEnc = NX_VidEncOpen(vpuencodetype, NULL );//NX_AVC_ENC NX_MP4_ENC NX_H263_ENC NX_JPEG_ENC
memset( &encInitParam, 0, sizeof(encInitParam) );
encInitParam.width = CameraWidth;
encInitParam.height = CameraHeight;
encInitParam.fpsNum = 10;
encInitParam.fpsDen = 1;
encInitParam.gopSize = 10;
encInitParam.bitrate =500000;
encInitParam.chromaInterleave = 1;
encInitParam.enableAUDelimiter = 0; // 就是这个标识,是否带AUD,原来是1,改成0
encInitParam.searchRange = 3;
if ( vpuencodetype == NX_JPEG_ENC )
{
encInitParam.chromaInterleave = 0;
encInitParam.jpgQuality = 90;//(pAppData->qp == 0) ? (90) : (pAppData->qp);
}
// Rate Control
encInitParam.maximumQp= 51;
encInitParam.disableSkip = 0;
encInitParam.initialQp = 23;
encInitParam.enableRC = 1;
encInitParam.RCAlgorithm =1;
encInitParam.rcVbvSize =-1;
就是改了上面参数,编码后的h264视频数据,就只有一个00 00 00 01.写入mp4v2容器。常用播放器都可以播放了,html网页也可以播放了。
可能有点乱,一般人估计也是一团雾水,记录于此,怕自己以后忘记。