问题描述
具体请查看代码
/frameworks/av/media/libstagefright/MPEG4Writer.cpp
1684bool MPEG4Writer::exceedsFileSizeLimit() {
.........
1701 // Be conservative in the estimate: do not exceed 95% of
1702 // the target file limit. For small target file size limit, though,
1703 // this will not help.
1704 return (nTotalBytesEstimate >= (95 * mMaxFileSizeLimitBytes) / 100);// 4G * 95% = 3.8G
1705}
解决方案
- 通过adb shell blkid dev/block/mmcblk1p1判断sdcard的限制,此时如果输出的结果:dev/block/mmcblk1p1: UUID="70CD-07EB" TYPE="vfat",则表示sdcard是fat型的,fat用32位表示文件的大小,天然就有2^32 = 4G的限制
这种情况下,软件无法处理,接受现状 - 在sdcard没有限制的情况下,可以通过软件在/frameworks/base/media/java/android/media/MediaRecorder.java的setVideoEncodingBitRate()中加入语句 setParameter("param-use-64bit-offset=1");来突破4G的限制,逻辑如下:从后往前查找 /frameworks/av/media/libstagefright/MPEG4Writer.cpp的param->findInt32(kKey64BitFileOffset, &use64BitOffset)如果设置了的话,就表示文件是64位表示的,也就没有4G的限制了,而use64BitOffset的值取决于kKey64BitFileOffset kKey64BitFileOffset的值又是在/frameworks/av/media/libmediaplayerservice/StagefrightRecorder.cpp中通过语句(*meta)->setInt32(kKey64BitFileOffset, mUse64BitFileOffset)设置的,也就意味着此时需要查看mUse64BitFileOffset的值,这个值又是借助status_t StagefrightRecorder::setParam64BitFileOffset(bool use64Bit)通过key == "param-use-64bit-offset"决定的,所以添加语句 setParameter("param-use-64bit-offset=1");就 意味着文件的大小可以超过4G
- 在https://android.googlesource.com/platform/frameworks/av/+/android-8.1.0_r14/media/libmediaplayerservice/StagefrightRecorder.cpp中也有看到如下处理方式(但此方法未经过实测验证,不能保证没有风险,仅供参考):Enable recording files larger than 4GB by forcing 64-bit file-offsets
in the writer, if application indicates max-file-size greater than 4GB.CRs-Fixed: 807377
Change-Id: Id1af5bdf3543af156e6d3d80be2e00c7df3b4134--- a/media/libmediaplayerservice/StagefrightRecorder.cpp
+++ b/media/libmediaplayerservice/StagefrightRecorder.cpp
@@ -87,6 +87,7 @@ static const char *kRecorderVideoLevel = "android.media.mediarecorder.video-enco
static const char *kRecorderCaptureFpsEnable = "android.media.mediarecorder.capture-fpsenable";
static const char *kRecorderCaptureFps = "android.media.mediarecorder.capture-fps";
static const char *kRecorderRotation = "android.media.mediarecorder.rotation";
+static const int64_t kMax32BitFileSize = 0x00ffffffffLL; // 4GB// To collect the encoder usage for the battery app
static void addBatteryData(uint32_t params) {
@@ -581,6 +582,10 @@ status_t StagefrightRecorder::setParamMaxFileSizeBytes(int64_t bytes) {
}mMaxFileSizeBytes = bytes;
+
+ // If requested size is >4GB, force 64-bit offsets
+ mUse64BitFileOffset |= (bytes >= kMax32BitFileSize);
+