实现数据循环缓存、缓存数据写入文件

2019-08-22  本文已影响0人  chenwr2018

开辟一块内存来循环缓存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;
}
上一篇下一篇

猜你喜欢

热点阅读