Page 1 of 1

ffmpeg录制mp4视频遇到的问题

Posted: 2024-06-07 11:25
by PWRJOY
您好,我按照您在这个链接viewtopic.php?p=2090#p2090提到的思路,实现ffmpeg封装h264流生成mp4文件的功能。现在出现了很奇怪的问题,我用第399行的代码可以实现录制mp4视频并播放,但是用第400行的代码录制的mp4视频就无法播放了。
从逻辑上,这仅仅是改变触发录制的时刻,不涉及ffmpeg录制的逻辑,难道是开发板还需要配置什么吗,您有什么排查的思路吗?
2024-06-07_190753.png
2024-06-07_190914.png
说明:
1、由于系统刚启动没有获取到摄像头画面是黑的,因此我添加了loopcount变量,用作一段延时。
2、如果有画面即录制,实时时间还没返回,因此第400行的目的只是检测当前系统时间然后再开启录制。
3、我尝试过clean重新编译,也是同样的现象。

修改rkipc的video.c的rkipc_get_venc_0函数如下:
主要就是在while中创建mp4文件,在获取到h264数据的时候写入到mp4,写入一定的帧数后关闭当前的mp4文件,创建下一个mp4文件。

Code: Select all

static void *rkipc_get_venc_0(void *arg) {
	LOG_DEBUG("#Start %s thread, arg:%p\n", __func__, arg);
	prctl(PR_SET_NAME, "RkipcVenc0", 0, 0, 0);
	VENC_STREAM_S stFrame;
	VI_CHN_STATUS_S stChnStatus;
	int ret = 0;
	int loopCount = 0,flag=0;
	stFrame.pstPack = malloc(sizeof(VENC_PACK_S));
	
	AVFormatContext *output_context = NULL;		//输出上下文

	while (g_video_run_) {
		//获取当前时间
		time_t t = time(NULL);
		struct tm tm = *localtime(&t);	

		loopCount++;
		if(loopCount==250){
//		if ((tm.tm_year + 1900 >= 2024)&&(record_is_run==0)){

			record_tm = tm;						//记录下开始录制的时间
			strftime(filename, sizeof(filename), "/root/%Y%m%d%H%M%S.mp4", &record_tm);
			output_context = create_mp4_file(filename);

			mp4_frame_index = 0;
			record_is_run = 1;
		}

		// 5.get the frame
		ret = RK_MPI_VENC_GetStream(VIDEO_PIPE_0, &stFrame, 1000);
		if (ret == RK_SUCCESS) {
			void *data = RK_MPI_MB_Handle2VirAddr(stFrame.pstPack->pMbBlk);
			if (g_rtsplive && g_rtsp_session_0) {
				pthread_mutex_lock(&g_rtsp_mutex);
				rtsp_tx_video(g_rtsp_session_0, data, stFrame.pstPack->u32Len,
				              stFrame.pstPack->u64PTS);
				rtsp_do_event(g_rtsplive);
				pthread_mutex_unlock(&g_rtsp_mutex);
			}
			if ((stFrame.pstPack->DataType.enH264EType == H264E_NALU_IDRSLICE) ||
			    (stFrame.pstPack->DataType.enH264EType == H264E_NALU_ISLICE) ||
			    (stFrame.pstPack->DataType.enH265EType == H265E_NALU_IDRSLICE) ||
			    (stFrame.pstPack->DataType.enH265EType == H265E_NALU_ISLICE)) {
				rk_storage_write_video_frame(0, data, stFrame.pstPack->u32Len,
				                             stFrame.pstPack->u64PTS, 1);
				if (enable_rtmp)
					rk_rtmp_write_video_frame(0, data, stFrame.pstPack->u32Len,
					                          stFrame.pstPack->u64PTS, 1);
			} else {
				rk_storage_write_video_frame(0, data, stFrame.pstPack->u32Len,
				                             stFrame.pstPack->u64PTS, 0);
				if (enable_rtmp)
					rk_rtmp_write_video_frame(0, data, stFrame.pstPack->u32Len,
					                          stFrame.pstPack->u64PTS, 0);
			}

			if(record_is_run){	
				if(mp4_frame_index == 0){	//第一帧不写入
					mp4_frame_index++;
				}else{
					write_video_frame(output_context, data, stFrame.pstPack->u32Len, (mp4_frame_index-1)*40);
					mp4_frame_index++;					
				}
			}

			if(mp4_frame_index==250){
				mp4_frame_index = 0;
				close_mp4_file(output_context);			//关闭mp4文件
				printf("close file\n");
				record_is_run = 0;
			}

			// 7.release the frame 释放当前帧
			ret = RK_MPI_VENC_ReleaseStream(VIDEO_PIPE_0, &stFrame);
			if (ret != RK_SUCCESS) {
				LOG_ERROR("RK_MPI_VENC_ReleaseStream fail %x\n", ret);
			}
		} else {
			LOG_ERROR("RK_MPI_VENC_GetStream timeout %x\n", ret);
		}
	}

	if (stFrame.pstPack)
		free(stFrame.pstPack);

	return 0;
}
使用ffmpeg的库创建mp4文件、写入视频帧、关闭mp4文件的代码如下图:
创建mp4文件.png
写入视频帧和关闭文件.png

Re: ffmpeg录制mp4视频遇到的问题

Posted: 2024-06-08 10:58
by Luckfox Taylor
由于我们工程师精力有限,我们无法保证对各种问题都能一一解答,很多细节东西要自己研究。感谢对幸狐的支持