rv1106_ipc例程中录制视频的时长错误

  • Crocodile wrote: 2024-05-30 3:59
    PWRJOY wrote: 2024-05-30 3:03 你好,我在rv1106_ipc的基础上做二次开发,主要功能是录制视频生成.mp4文件。
    我需要在特定时刻触发视频录制功能,而原有的例程是在.ini文件中固定录制时长duration.
    虽然修改代码后也能在特定时刻生成.mp4文件,但是由于信号量rk_storage_muxer_group[id].g_storage_signal没有获取,录制视频流异常结束导致文件时长错误,录制了15分钟但文件信息只有2秒。
    2024-05-30_111508.png
    storage.c中修改的函数如下:

    Code: Select all

    //每小时0,15,30,45分钟触发录制
    static void *rk_storage_record(void *arg) {
    	int *id_ptr = arg;
    	int id = *id_ptr;
    	printf("id: %d, #Start %s thread, arg:%p\n", id, __func__, arg);
    
    	//设置进程名 rk_storage_record
    	prctl(PR_SET_NAME, "rk_storage_record", 0, 0, 0);
    
    	// 如果开启存储
    	while (g_storage_record_flag[id] && record_flag[id] == 1) {
    		//获取当前时间
    		time_t t = time(NULL);
    		struct tm tm = *localtime(&t);
    		//生成文件名
    		snprintf(rk_storage_muxer_group[id].file_name, 512, "%s/%d%02d%02d%02d%02d%02d.%s",
    		         rk_storage_muxer_group[id].record_path, tm.tm_year + 1900, tm.tm_mon + 1,
    		         tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec,
    		         rk_storage_muxer_group[id].file_format);
    		// 打印文件名
    		LOG_INFO("[%d], file_name is %s\n", id, rk_storage_muxer_group[id].file_name);
    		// 互斥锁
    		pthread_mutex_lock(&g_rkmuxer_mutex);
    		// 停止旧的muxer
    		rk_storage_muxer_group[0].g_record_run_ = 0;
    		rkmuxer_deinit(id);
    		// 开始新的录制(文件名、视频帧、音频帧)
    		rkmuxer_init(id, NULL, rk_storage_muxer_group[id].file_name,
    		             &rk_storage_muxer_group[id].g_video_param,
    		             &rk_storage_muxer_group[id].g_audio_param);
    		rk_storage_muxer_group[0].g_record_run_ = 1;
    		pthread_mutex_unlock(&g_rkmuxer_mutex);
    		// 等待 file_duration
    //		rk_signal_wait(rk_storage_muxer_group[id].g_storage_signal,
    //		               rk_storage_muxer_group[id].file_duration * 1000);
    
            // 等待直到下一个触发点(0, 15, 30, 45分钟) 
            int next_minute = (tm.tm_min / 15 + 1) * 15; 
            if (next_minute >= 60) { 
                next_minute = 0; 
                tm.tm_hour += 1; 
            } 
            tm.tm_min = next_minute; 
            tm.tm_sec = 0; 
            time_t next_trigger_time = mktime(&tm); 
            time_t current_time; 
            
            do { 
                current_time = time(NULL); 
                sleep(1); 
            } while (current_time < next_trigger_time);
    
    	}
    	pthread_mutex_lock(&g_rkmuxer_mutex);
    	rk_storage_muxer_group[0].g_record_run_ = 0;
    	rkmuxer_deinit(id);
    	pthread_mutex_unlock(&g_rkmuxer_mutex);
    
    	return NULL;
    }
    结合开发手册的结构框图,所涉及的部分用红圈全出。
    2024-05-30_105818.png
    在修改storage.c代码过程中多次看到程序使用muxer复用器相关功能,但是却没有找到#include "rkmuxer.h"这个头文件的位置,麻烦告知下。

    想找到复用器muxer生成.mp4部分的源码,排查问题,或者您有别的解决方式。
    您好,rkmuxer.h和相关的库在<SDK>/media/common_algorithm/common_algorithm/misc 下,rkmuxer部分的源码Rockchip是没有公开的.
    根据rkipc的文档来看,rkmuxer的作用应该是结合音频和视频编码为mp4文件,而 VENC 目前能支持硬件编码的格式MJPEG和H264,如果您对音频没有需求的话可以考虑单独走视频录制,rkmuxer对原始视频流的封装部分可以自己实现(比如调用ffmpeg库,比较耗时的编码交给VENC实现了),这样的话需求就好实现很多,RKMPI的资料比较完善且灵活性更高,这样可以跳过对rkmuxer可能存在的问题。
    mp4的使用需求之前也有其它论坛成员提到,后续我也会测试一下rkmuxer的使用,如果有新的进展我会在wiki进行更新。
  • 感谢您的回复!
    能够再解释下“单独走视频录制”这个是什么意思,有什么资料可以参考吗?
    Last edited by PWRJOY on 2024-05-30 4:47, edited 2 times in total.
  • 把storage.c中修改的代码还原,只配置.ini文件,生成mp4仍然会出现视频时长只有2秒的问题。
    所以rkipc的例程本身还是有bug的,您可以复现下。
  • PWRJOY wrote: 2024-05-30 4:21 感谢您的回复!
    能够再解释下“单独走视频录制”这个是什么意思,有什么资料可以参考吗?
    单独走视频录制就是不要使用rkipc中的那套结构,使用新的框架来实现
    rkipc_MP4.jpg
    如果您打算保存的视频对分辨率还是格式有需求可另外绑定一套VENC,不需要的话就从原本的输出作处理即可。
    实现方法可以参考Rockchip_Developer_Guide_Linux_RKIPC_CN.pdf 中的内容,添加新的参数并实现相关业务代码(方便后续管理)。当然rkipc的框架比较复杂,您也可以重新构建工程,这样在很多组件的调控上更加直观一点,不依赖ini文件可以大大简化工程,wiki中的RKMPI章节也提供了基础框架,您可以在上面的基础上作修改。
    rkipc虽然作为rv1106的核心功能,但是本身的完成度有限,很多功能或许是实现有问题或者文档没有说明清楚,在测试过程中不能实现。由于rkipc使用的控制框架比较独特,我们不确定进行维护后会不会和后续Rockchip更新的冲突,所以短期内没有对rkipc进行深入维护的打算。在Rockchip下一个更新后我们会系统性地测试rkipc并更新SDK中的版本,确保rkipc能够正常使用。