小言_互联网的博客

Qt开发笔记之编码h264码流并封装mp4(六):ubuntu平台编译mp4v2并封装mp4

370人阅读  评论(0)

若该文为原创文章,未经允许不得转载
原博主博客地址:https://blog.csdn.net/qq21497936
原博主博客导航:https://blog.csdn.net/qq21497936/article/details/102478062
本文章博客地址:https://blog.csdn.net/qq21497936/article/details/103708743

目录

前言

Ubuntu下mp4v2库编译

步骤一:下载、放入编译文件夹并解压

步骤二:配置configre

步骤三:编译make,错误‘\0’

Demo演示

H264转mp4

关键代码

结论

入坑一:封装出的mp4文件出现马赛克或者模糊的情况。


Qt开发笔记之编码h264码流并封装mp4

Qt开发笔记之编码h264码流并封装mp4(一):x264介绍、windows平台x264库编译

Qt开发笔记之编码h264码流并封装mp4(二):windows平台x264添加mp4支持,gpac库的介绍与编译

Qt开发笔记之编码h264码流并封装mp4(三):Qt使用x264库对.yuv文件编码为.h264文件

Qt开发笔记之编码h264码流并封装mp4(四):mp4v2库的介绍和windows平台编译

Qt开发笔记之编码h264码流并封装mp4(五):ubuntu平台编译x264》

Qt开发笔记之编码h264码流并封装mp4(六):ubuntu平台编译mp4v2并封装mp4

 

    Qt开发笔记之编码h264码流并封装mp4(六):ubuntu平台编译mp4v2并封装mp4

 

前言

       前面尝试在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

 

关键代码


  
  1. bool X264Manager::testH264ToMp4(QString h264File, QString destFile)
  2. {
  3. bool ret = false;
  4. // 检测输入文件
  5. if(!h264File.endsWith( ".h264"))
  6. {
  7. qDebug() << __FILE__ << __LINE__ << "Failed to recgnize ext:" << h264File;
  8. return ret;
  9. }
  10. // 检测输出文件
  11. if(destFile.isEmpty())
  12. {
  13. destFile = h264File;
  14. destFile.truncate(destFile.lastIndexOf( ".yuv"));
  15. destFile += ".mp4";
  16. } else if(!destFile.endsWith( ".mp4"))
  17. {
  18. qDebug() << __FILE__ << __LINE__ << "Failed to recgnize ext:" << destFile;
  19. return ret;
  20. }
  21. qDebug() << __FILE__ << __LINE__ << h264File << "to" << destFile;
  22. FILE *pIn = NULL;
  23. unsigned char *pBuf = ( unsigned char *) malloc( 1024* 1024);
  24. unsigned char *pBuf2 = ( unsigned char *) malloc( 1024* 1024);
  25. unsigned char *pNalu = NULL;
  26. unsigned char naluType;
  27. int len;
  28. int num = 0;
  29. MP4FileHandle pHandle = NULL;
  30. MP4TrackId videoId;
  31. int width = 640;
  32. int height = 360;
  33. int frameRate = 25;
  34. // int timeScale = 9600;
  35. int timeScale = 1000;
  36. int addStream = 1;
  37. // 打开.h264流文件
  38. pIn = fopen(h264File.toUtf8().data(), "rb");
  39. if(!pIn)
  40. return -1;
  41. // 创建mp4文件
  42. pHandle = MP4Create(destFile.toUtf8().data(), 0);
  43. // pHandle = MP4CreateEx(destFile.toUtf8().data(), 0, 1, 1, 0, 0, 0, 0);
  44. if(pHandle == MP4_INVALID_FILE_HANDLE)
  45. {
  46. printf( "ERROR:Create mp4 handle fialed.\n");
  47. return -1;
  48. }
  49. // 设置timescale
  50. MP4SetTimeScale(pHandle, timeScale);
  51. while( 1)
  52. {
  53. len = getNalu(pIn, pBuf);
  54. {
  55. printf( "len(%d)\n", len);
  56. }
  57. if (len <= 0)
  58. break;
  59. if (pBuf[ 0] != 0 || pBuf[ 1] != 0 || pBuf[ 2] != 0 || pBuf[ 3] != 1)
  60. continue;
  61. len -= 4;
  62. pNalu = pBuf+ 4;
  63. naluType = pNalu[ 0]& 0x1F;
  64. switch (naluType)
  65. {
  66. case 0x07: // SPS
  67. printf( "------------------------------------\n");
  68. printf( "sps(%d)\n", len);
  69. if (addStream)
  70. {
  71. videoId = MP4AddH264VideoTrack
  72. (pHandle,
  73. timeScale, // 一秒钟多少timescale
  74. timeScale/frameRate, // 每个帧有多少个timescale
  75. width, // width
  76. height, // height
  77. pNalu[ 1], // sps[1] AVCProfileIndication
  78. pNalu[ 2], // sps[2] profile_compat
  79. pNalu[ 3], // sps[3] AVCLevelIndication
  80. 3); // 4 bytes length before each NAL unit
  81. if (videoId == MP4_INVALID_TRACK_ID)
  82. {
  83. printf( "Error:Can't add track.\n");
  84. return -1;
  85. }
  86. MP4SetVideoProfileLevel(pHandle, 0x7F);
  87. addStream = 0;
  88. }
  89. MP4AddH264SequenceParameterSet(pHandle, videoId, pNalu, len);
  90. break;
  91. case 0x08: // PPS
  92. // printf("pps(%d)\n", len);
  93. MP4AddH264PictureParameterSet(pHandle, videoId, pNalu, len);
  94. break;
  95. default:
  96. memcpy(pBuf + 4, pBuf, len);
  97. pBuf[ 0] = (len>> 24)& 0xFF;
  98. pBuf[ 1] = (len>> 16)& 0xFF;
  99. pBuf[ 2] = (len>> 8)& 0xFF;
  100. pBuf[ 3] = (len>> 0)& 0xFF;
  101. printf( "slice(%d, %d, %d, %d)(%d, %d, %d, %d)\n", \
  102. pBuf[ 0], pBuf[ 1], pBuf[ 2], pBuf[ 3], pBuf[ 4], \
  103. pBuf[ 5], pBuf[ 6], pBuf[ 7]);
  104. MP4WriteSample(pHandle, videoId, pBuf, len+ 4,\
  105. MP4_INVALID_DURATION, 0, 1);
  106. break;
  107. }
  108. }
  109. free(pBuf);
  110. fclose(pIn);
  111. MP4Close(pHandle, 0);
  112. }

 

结论

可能换一个mp4库尝试,验证一下。

 

入坑一:封装出的mp4文件出现马赛克或者模糊的情况。

尝试:

       自己写代码,网上代码,自己对比文件(读者有兴趣可以弄,暂未弄),暂未解决。

解决方法:

       暂未解决,有时间再弄,短期内决定尝试换一个库,同样期待大佬定位并解决mp4v2库这个问题,解决了欢迎联系笔者:QQ21497936,提供解决方法。

 

原博主博客地址:https://blog.csdn.net/qq21497936
原博主博客导航:https://blog.csdn.net/qq21497936/article/details/102478062
本文章博客地址:https://blog.csdn.net/qq21497936/article/details/103708743


转载:https://blog.csdn.net/qq21497936/article/details/103708743
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场