前言
前面尝试在windows下编译,实在过不了,只好转战至ubuntu。
Ubuntu下mp4v2库编译
步骤一:下载、放入编译文件夹并解压
步骤二:配置configre
步骤三:编译make,错误‘\0’
直接修改下源码
继续编译。
Demo演示
H264转mp4
注意:转换后的结果不对,原来效果为:
笔者尝试至少4套不同人封装的mp4v2代码,以及将视频文件给到专做视频的使用mp4v2结果也是一样,没有再深入去研究,欢迎读者解决该问题,笔者后续有时间会继续研究。
使用ffmpeg命令转mp4是正常的,转换指令如下:
ffmpeg -i cuc_ieschool_640x360_yuv420p.h264 -vcodec copy -f mp4 1.mp4
关键代码
bool X264Manager::testH264ToMp4(QString h264File, QString destFile) { bool ret = false; // 检测输入文件 if(!h264File.endsWith(".h264")) { qDebug() << __FILE__ << __LINE__ << "Failed to recgnize ext:" << h264File; return ret; } // 检测输出文件 if(destFile.isEmpty()) { destFile = h264File; destFile.truncate(destFile.lastIndexOf(".yuv")); destFile += ".mp4"; }else if(!destFile.endsWith(".mp4")) { qDebug() << __FILE__ << __LINE__ << "Failed to recgnize ext:" << destFile; return ret; } qDebug() << __FILE__ << __LINE__ << h264File << "to" << destFile; FILE *pIn = NULL; unsigned char *pBuf = (unsigned char *)malloc(1024*1024); unsigned char *pBuf2 = (unsigned char *)malloc(1024*1024); unsigned char *pNalu = NULL; unsigned char naluType; int len; int num = 0; MP4FileHandle pHandle = NULL; MP4TrackId videoId; int width = 640; int height = 360; int frameRate = 25; // int timeScale = 9600; int timeScale = 1000; int addStream = 1; // 打开.h264流文件 pIn = fopen(h264File.toUtf8().data(), "rb"); if(!pIn) return -1; // 创建mp4文件 pHandle = MP4Create(destFile.toUtf8().data(), 0); // pHandle = MP4CreateEx(destFile.toUtf8().data(), 0, 1, 1, 0, 0, 0, 0); if(pHandle == MP4_INVALID_FILE_HANDLE) { printf("ERROR:Create mp4 handle fialed.\n"); return -1; } // 设置timescale MP4SetTimeScale(pHandle, timeScale); while(1) { len = getNalu(pIn, pBuf); { printf("len(%d)\n", len); } if (len <= 0) break; if (pBuf[0] != 0 || pBuf[1] != 0 || pBuf[2] != 0 || pBuf[3] != 1) continue; len -= 4; pNalu = pBuf+4; naluType = pNalu[0]&0x1F; switch (naluType) { case 0x07: // SPS printf("------------------------------------\n"); printf("sps(%d)\n", len); if (addStream) { videoId = MP4AddH264VideoTrack (pHandle, timeScale, // 一秒钟多少timescale timeScale/frameRate, // 每个帧有多少个timescale width, // width height, // height pNalu[1], // sps[1] AVCProfileIndication pNalu[2], // sps[2] profile_compat pNalu[3], // sps[3] AVCLevelIndication 3); // 4 bytes length before each NAL unit if (videoId == MP4_INVALID_TRACK_ID) { printf("Error:Can't add track.\n"); return -1; } MP4SetVideoProfileLevel(pHandle, 0x7F); addStream = 0; } MP4AddH264SequenceParameterSet(pHandle, videoId, pNalu, len); break; case 0x08: // PPS // printf("pps(%d)\n", len); MP4AddH264PictureParameterSet(pHandle, videoId, pNalu, len); break; default: memcpy(pBuf + 4, pBuf, len); pBuf[0] = (len>>24)&0xFF; pBuf[1] = (len>>16)&0xFF; pBuf[2] = (len>>8)&0xFF; pBuf[3] = (len>>0)&0xFF; printf("slice(%d, %d, %d, %d)(%d, %d, %d, %d)\n", \ pBuf[0], pBuf[1], pBuf[2], pBuf[3], pBuf[4], \ pBuf[5], pBuf[6], pBuf[7]); MP4WriteSample(pHandle, videoId, pBuf, len+4,\ MP4_INVALID_DURATION, 0, 1); break; } } free(pBuf); fclose(pIn); MP4Close(pHandle, 0); }
结论
可能换一个mp4库尝试,验证一下。
入坑一:封装出的mp4文件出现马赛克或者模糊的情况。
尝试:
自己写代码,网上代码,自己对比文件(读者有兴趣可以弄,暂未弄),暂未解决。
解决方法:
暂未解决,有时间再弄,短期内决定尝试换一个库,同样期待大佬定位并解决mp4v2库这个问题,解决了欢迎联系笔者:QQ21497936,提供解决方法。