开辟一块内存来循环缓存H264码流,避免碰撞导致录像数据无法写入外存储器中。能够及时将内存碰撞前的一段视频及时存储到内置Flash中。
/************************************************************************
**函数:dvr_h264_prerec_start
**功能:循环缓存H264码流
**参数:
[in] channel - 通道号,从1开始
[in] type - 1:视频,2:音频
[in] u64timestamp - 时间戳(单位us)
[in] tm - 底层产生数据时的系统时间
[in] buf - 音视频数据
[in] buf_len - buf数据长度(in bytes)
**返回:失败返回-1,成功返回0
************************************************************************/
INT32S dvr_h264_prerec_start(CHNNO_APP channel,
INT8U type,
INT64U u64timestamp,
time_t tm,
const void *buf,
INT32U buf_len
)
{
INT32U size_to_max, ret;
H264_BUFFER_T *pbuf;
char save_file[100] = {0};
INT32S fd, len;
ret = dvr_h264_prerec_init(channel);
if (0 != ret) {
FK_TRACE_ERROR("[cwr] dvr_h264_prerec_init fail\n");
return -1;
}
pbuf = &s_h264_buf[channel];
/* 循环缓存海思传过来的H264码流 */
if (pbuf->H264_buf_offset + buf_len >= H264_MAXBUFSZIE) {
size_to_max = H264_MAXBUFSZIE - pbuf->H264_buf_offset;
if (size_to_max < buf_len) {
FK_TRACE_INFO("[cwr] buf cycle\n");
memcpy(pbuf->h264_buf + pbuf->H264_buf_offset, buf, size_to_max);
memcpy(pbuf->h264_buf, (INT8S *)buf + size_to_max, buf_len - size_to_max);
pbuf->H264_buf_offset = (buf_len - size_to_max);
}
} else {
memcpy(pbuf->h264_buf + pbuf->H264_buf_offset, buf, buf_len);
pbuf->H264_buf_offset += buf_len;
}
/* 检测到碰撞将缓存数据存储内置Flash */
if (true == g_fat_crash && false == pbuf->save_h264_state) {
snprintf(save_file, 100, "%s/crash_chn%d_save_h264.mp4", H264_SAVE_PATH, channel);
fd = open(save_file, O_RDWR|O_CREAT|O_TRUNC);//覆盖原先数据O_TRUNC
if(fd < 0) {
FK_TRACE_ERROR("[cwr] create flash file fail\n");
return -1;
}
/* 先写缓存区中旧的数据 */
len = write(fd, pbuf->h264_buf + pbuf->H264_buf_offset, H264_MAXBUFSZIE - pbuf->H264_buf_offset);
FK_TRACE_ERROR("[cwr] len = %d, H264_MAXBUFSZIE - pbuf->H264_buf_offset = %d\n", len, H264_MAXBUFSZIE - pbuf->H264_buf_offset);
if (len != (H264_MAXBUFSZIE - pbuf->H264_buf_offset)) {
FK_TRACE_ERROR("[cwr] write data fail %d\n", fd);
if (0 != errno) {
FK_TRACE_ERROR("[cwr] [err data] write data errno=%d (%s)!\n", errno, strerror(errno));
}
close(fd);
return -1;
}
/* 接着写缓存中新的数据 */
len = write(fd, pbuf->h264_buf, pbuf->H264_buf_offset);
if (len != pbuf->H264_buf_offset) {
FK_TRACE_ERROR("[cwr] write data fail %d\n", fd);
if (0 != errno) {
FK_TRACE_ERROR("[cwr] [err data] write data errno=%d (%s)!\n", errno, strerror(errno));
}
close(fd);
return -1;
}
close(fd);
FK_TRACE_INFO("[cwr] dvr_save_h264 file %s save suc\n", save_file);
pbuf->save_h264_state = true;
}
return 0;
}