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

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

前言

前面尝试在windows下编译,实在过不了,只好转战至ubuntu。

Ubuntu下mp4v2库编译

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

2aaf5a898212eea6e5fc9c91b12876d1.png

步骤二:配置configre

962bafb4853ece5a8c5dcf5eca2d37d8.png

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

9218eb94de78a1be9519f1da29b53257.png

直接修改下源码

cdea7d3d6e76a12e0a944dd3a1812238.png

继续编译。

Demo演示

H264转mp4

b2ff6f086fda263ee09eef0f2392189a.png

注意:转换后的结果不对,原来效果为:

043544af7365a8f155aab2fb34b8558a.png

笔者尝试至少4套不同人封装的mp4v2代码,以及将视频文件给到专做视频的使用mp4v2结果也是一样,没有再深入去研究,欢迎读者解决该问题,笔者后续有时间会继续研究。

使用ffmpeg命令转mp4是正常的,转换指令如下:

ffmpeg -i cuc_ieschool_640x360_yuv420p.h264 -vcodec copy -f mp4 1.mp4

79b185ef59235f20462276b5bf162638.png

关键代码

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文件出现马赛克或者模糊的情况。

尝试:

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

f7b654d5db90f325989be60b5e15a207.png

解决方法:

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

本文同步分享在 博客“红胖子(AAA红模仿)”(CSDN)。

如有侵权,请联系 support@oschina.cn 删除。

本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值