这是个之前从没碰到过的问题, 记录一下这无语的跟踪过程 ...
两周前的某一天, 忽然一封邮件转过来, 测试那边描述手机录像在内置卡录满状态下会出问题, 录出的文件播不了; 按说, 磁盘录满根本不是个大事, Camera APK 会统计内置卡或者外置卡的剩余可用空间, 减掉个保留值设下来, 然后 MPEG4Writer 还会按这个值配个 95% 的折扣 mMaxFileSizeLimitBytes, 录像过程中会时刻比对录像的临时文件 .mp4.tmp 和这个 mMaxFileSizeLimitBytes, 随时终止录像并上报 MAX_FILESIZE_REACHED 的通知, 所以只要录像时不会有其他进程后台写文件的状况, 是肯定不会出现录像文件写失败的; 这套处理逻辑早已成熟, 直可追溯到上上届常委时期; 而且现在 google 还为了磁盘录满, 增加了 splitting 的处理, 无懈可击 ... // MAGIC1. DO NOT TOUCH. BY 冗戈微言 http://blog.youkuaiyun.com/leonxu_sjtu/
说了那么多背景,那测试反映的到底是什么情况?
const void *ptr, size_t size, size_t nmemb) {
...
} else {
ALOGW("mWriteMoovBoxToMemory false - write size=%lld, nmemb=%lld", (long long)size,(long long)nmemb);
ssize_t rt;
rt = ::write(mFd, ptr, size * nmemb);
ALOGW("mWriteMoovBoxToMemory write rt = %lld, errno = %d-%s", (long long)rt, errno, strerror(errno));
mOffset += bytes;
}
return bytes;
}
对应的 log :
01-11 06:18
两周前的某一天, 忽然一封邮件转过来, 测试那边描述手机录像在内置卡录满状态下会出问题, 录出的文件播不了; 按说, 磁盘录满根本不是个大事, Camera APK 会统计内置卡或者外置卡的剩余可用空间, 减掉个保留值设下来, 然后 MPEG4Writer 还会按这个值配个 95% 的折扣 mMaxFileSizeLimitBytes, 录像过程中会时刻比对录像的临时文件 .mp4.tmp 和这个 mMaxFileSizeLimitBytes, 随时终止录像并上报 MAX_FILESIZE_REACHED 的通知, 所以只要录像时不会有其他进程后台写文件的状况, 是肯定不会出现录像文件写失败的; 这套处理逻辑早已成熟, 直可追溯到上上届常委时期; 而且现在 google 还为了磁盘录满, 增加了 splitting 的处理, 无懈可击 ... // MAGIC1. DO NOT TOUCH. BY 冗戈微言 http://blog.youkuaiyun.com/leonxu_sjtu/
说了那么多背景,那测试反映的到底是什么情况?
自己试了下, 将内置卡塞到接近塞满, 此时开始录像, 录出的文件确实播不了, 体现在这 mp4 文件的 moov header 在偏移量第 0x1000 后, 全部是零数据, 仿佛写不进去:
看到 0x1000 这么整整齐齐, 很可能是文件系统的锅啊, 于是在 MPEG4Writer 代码里调用 write 的地方加了 log :// MAGIC2. DO NOT TOUCH. BY 冗戈微言 http://blog.youkuaiyun.com/leonxu_sjtu/
size_t MPEG4Writer::write(const void *ptr, size_t size, size_t nmemb) {
...
} else {
ALOGW("mWriteMoovBoxToMemory false - write size=%lld, nmemb=%lld", (long long)size,(long long)nmemb);
ssize_t rt;
rt = ::write(mFd, ptr, size * nmemb);
ALOGW("mWriteMoovBoxToMemory write rt = %lld, errno = %d-%s", (long long)rt, errno, strerror(errno));
mOffset += bytes;
}
return bytes;
}
对应的 log :
01-11 06:18