ireader / media-server

RTSP/RTP/RTMP/FLV/HLS/MPEG-TS/MPEG-PS/MPEG-DASH/MP4/fMP4/MKV/WebM
MIT License
3.05k stars 1.07k forks source link

[技术咨询] mp4 长时间录制内存增长 #264

Open HR1025 opened 1 year ago

HR1025 commented 1 year ago

我看到在 libmov/source/mov-internal.h 定义了:

struct mov_sample_t
{
    int flags; // MOV_AV_FLAG_KEYFREAME
    int64_t pts; // track mdhd timescale
    int64_t dts;

    void* data;
    uint64_t offset; // is a 32 or 64 bit integer that gives the offset of the start of a chunk into its containing media file.
    uint32_t bytes;

    uint32_t sample_description_index;
    uint32_t samples_per_chunk; // write only
    uint32_t first_chunk; // write only
};

写入 mp4 的每一帧都需要一个 mov_sample_t 来保存信息; 在不考虑内存对齐的情况下,一个结构体应该是 64 字节,如果视频流的规格是30帧每秒,那么一个钟为 mov_sample_t 分配的内存为: 60 60 30 * 64 = 6,912,000 bytes ≈ 6MB 对于嵌入式设备而言还是相当客观的内存.

尤其对于并发长时间录制,内存在逐步增长; 比如七路,两小时业务分一次片,在分片时已经快吃掉近百兆的物理内存了. 而且底部的内存是用 realloc 进行分配的, 是连续的大内存空间, 由于内存碎片化的原因更加难以提供. 这里的统计是单纯计算视频流的,实际上由于音频流,内存的增长会更加明显.

针对这种场景,有什么好的方法吗?

我的想法是不是可能可以把 mov_sample_t 的内存管理给交使用方,这样我就可以进行内存管理了;就像 media-server 之前的做法一样.

HR1025 commented 1 year ago

同时 mp4 这种文件比较怕断电,把这部分的内存管理交给调用方,还可以做到断电恢复的效果.

fmp4 确实有这些特性,或者用流式 ts 进行存储;不过很多客户都还在用 win7, fmp4 的兼容性不太好,比如 win 自带播放器就不能进行定位跳转, 所以我还是想尽力尝试 mp4.

ireader commented 1 year ago

可以,这块占用的内存确实比较多,我考虑下设计方案。

初步想法是提供alloc/free回调。

HR1025 commented 1 year ago

感谢; 我可以修改, 我可以改完提交一个 draft 吗

ireader commented 1 year ago

可以的,非常欢迎提PR!