基于富瀚6630移植mp4v2库将h264流保存为mp4文件

本文详细介绍如何在富瀚6630平台上移植mp4v2库,实现H264视频流转换为MP4文件的过程,包括编译mp4v2库、整合到富瀚工程并提供关键代码片段。步骤包括配置库、创建MP4文件、处理帧流和写入数据。附带工程下载链接。
摘要由CSDN通过智能技术生成

移植mp4v2库

mp4v2-2.0.0.tar下载

  1. 编译静态库
 cd mp4v2-2.0.0/
 rm -fr build/
 mkdir build/
 cd build/
 ../configure --host=arm-mol-linux-uclibcgnueabihf --prefix=/home/lxr/lxr/test/
 /*--host用来指定生成库工具的编译器,如果是在x86上面执行的,则默认的就可以,即不用配置。
--prefix用来指定生成工具的路径
*/
 make
 make install
 make install-man
  1. 把生成的头文件和库拷贝到富瀚工程路径中,并修改Makefile
    在这里插入图片描述

富瀚工程添加h264转化Mp4代码

#ps:注意看我//mp4:带头的注释,这里我就只粗略解释一下几个关键函数
详细问题可以私聊我

static void *_thread_venc_data(void *param)
{	
	FY_S32 i,j,k;
	FY_S32 s32ChnTotal;
	VENC_STREAM_S stStream;
	FY_S32 s32Ret;
	FY_S32 VencFd[LXR_VENC_MAX_CHN_NUM];
	FY_S32 maxfd = 0;
	struct timeval TimeoutVal;
	fd_set read_fds;
	LXRFrame_t stVideoData;
	FY_S32 streamID = 0;
	FY_S32 conn = 0;

	//prctl(PR_SET_NAME, "GetVeuStream");

	s32ChnTotal = LXR_VENC_MAX_CHN_NUM;

	/******************************************
	 step 1:  check & prepare save-file & venc-fd
	******************************************/		

	for (i = 0; i < s32ChnTotal; i++)
	{				
	   /* Set Venc Fd. */
		VencFd[i] = FY_MPI_VENC_GetFd(i);
		if (VencFd[i] < 0)
		{
			printf("HI_MPI_VENC_GetFd failed with %#x!\n", VencFd[i]);
			return NULL;
		}
		if (maxfd <= VencFd[i])
		{
			maxfd = VencFd[i];
		}		
	}

	memset(&stStream, 0, sizeof(stStream));
	stStream.pstPack = (VENC_PACK_S*)malloc(sizeof(VENC_PACK_S) * 10);
	if (NULL == stStream.pstPack)
	{
		printf("malloc stream pack failed!\n");
		return NULL;
	}
	/******************************************
	 step 2:  Start to get streams of each channel.
	 ******************************************/
	 
	//mp4:CreateMP4File创建mp4文件
	MP4FileHandle hMp4File = CreateMP4File("pfileMp4.mp4",1920,1080); 
	FY_S32 file_length = 1*10;
	FY_S32 start_record = _mrecord_getsec();

    while (1)
	{
		FY_S32 now = _mrecord_getsec();
		if((now-start_record)>=file_length){
			//mp4:录像时间结束关闭录像
			CloseMP4File(hMp4File);
			printf("record finish\n");
			break;
		}

		FD_ZERO(&read_fds);
		for (i = 0; i < s32ChnTotal; i++)
		{
			FD_SET(VencFd[i], &read_fds);
		}


		TimeoutVal.tv_sec  = 2;
		TimeoutVal.tv_usec = 0;
		s32Ret = select(maxfd+1, &read_fds, NULL, NULL, &TimeoutVal);
		if (s32Ret < 0)
		{
			printf("venc select failed!\n");
			break;
		}
		else if (0 == s32Ret)
		{
			usleep(40000);
			printf("venc select time out!\n");
			continue;
		}
		else
		{
			for (i = 0; i < s32ChnTotal; i++)
			{
				int vi_chn = i%VI_CHN_NUM;
				if(LXR_Vi_GetConnectStatus(vi_chn) == 0)
				{
					continue;
				}
				if (FD_ISSET(VencFd[i], &read_fds))
				{					
					/*******************************************************
					step 2.1 : query how many packs in one-frame stream.
					*******************************************************/
					VENC_CHN_STAT_S stStat;
					s32Ret = FY_MPI_VENC_Query(i, &stStat);
					if (FY_SUCCESS != s32Ret)
					{
						printf("FY_MPI_VENC_Query chn[%d] failed with %#x!\n", i, s32Ret);
						break;
					}
					/*******************************************************
					step 2.2 :suggest to check both u32CurPacks and u32LeftStreamFrames at the same time,for example:
					 if(0 == stStat.u32CurPacks || 0 == stStat.u32LeftStreamFrames)
					 {						SAMPLE_PRT("NOTE: Current  frame is NULL!\n");
						continue;
					 }
					 *******************************************************/
					//printf("dcy test porting FY_MPI_VENC_Query =%d \n", stStat.u32LeftStreamFrames);
					if (0 == stStat.u32LeftStreamFrames)
					{
						//SAMPLE_PRT("NOTE: chn%d is null!\n", i);
						//u32ContinQueryFailCnt++;
						continue;
					}

					/*******************************************************
					 step 2.4 : call mpi to get one-frame stream
					*******************************************************/
					stStream.u32PackCount = stStat.u32CurPacks;
					if(stStream.u32PackCount > 0)
					{
						//printf("dcy test porting enc ch=%d\n", i);
						s32Ret = FY_MPI_VENC_GetStream(i, &stStream, FY_TRUE);
					}
					if (FY_SUCCESS != s32Ret)
					{
						printf("dcy test get stream fail\n");
						continue;
					}
					else
					{
						//只接受第一通道数据
						if(i==0){

							for (k= 0; k < stStream.u32PackCount; k++)
							{
								printf("[lxr_test_venc][func=%s][LINE=%d][data0=%d][data1=%d][data2=%d][data3=%d]\n",__func__,__LINE__,\
								stStream.pstPack[k].pu8Addr[0],stStream.pstPack[k].pu8Addr[1],stStream.pstPack[k].pu8Addr[2],stStream.pstPack[k].pu8Addr[3]);
								stVideoData.buffer = stStream.pstPack[k].pu8Addr + stStream.pstPack[k].u32Offset;
								printf("[lxr_test_venc][func=%s][LINE=%d][data0=%d][data1=%d][data2=%d][data3=%d][nalu_head=0x%x]\n",__func__,__LINE__,\
								stVideoData.buffer[0],stVideoData.buffer[1],stVideoData.buffer[2],stVideoData.buffer[3],stVideoData.buffer[4]);
								stVideoData.len = stStream.pstPack[k].u32Len - stStream.pstPack[k].u32Offset;
								//mp4:从富瀚获取流接口接受到数据后,通过WriteH264Data_lxr解析到MP4文件
								WriteH264Data_lxr(hMp4File,&stVideoData);
								//u32Offset:码流包中有效数据与码流包首地址 pu8Addr 的偏移
							}
						}					
					}

					/*******************************************************
					 step 2.6 : release stream
					 *******************************************************/
					s32Ret = FY_MPI_VENC_ReleaseStream(i, &stStream);
					if (FY_SUCCESS != s32Ret)
					{
					  break;
					}					
				}
				//usleep(10*1000);
			}

make

make myboard=mc6630/demoboard test

成果图

在这里插入图片描述

MP4代码下载(附上整个工程)

点这点这~~

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

I&You

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值