间隔问题3 [No. 58]

本文介绍了一种在O(NlgN)时间复杂度内找到被最多区间覆盖点的方法。通过将所有区间的起点和终点排序,并跟踪当前覆盖的区间数量,可以确定一个点,使得穿过该点的区间数量达到最大。

问题:

给一组间隔,找出一个点,使得穿过改点的间隔数量最大, 时间复杂度不能超过 O(N lg N)。比如有一组间隔为[1, 5] [ 3, 7] [2, 4] [8, 9], 那么对于点 3.5, 有3个间隔都包含这个点,但是对于点 8.5,只有一个间隔包含该点。所以,最后答案是 3.5. (当然,3.6, 或者 3.7 都可以)。

分析:

对于一组间隔,我们把它所有间隔的起始值和结束值放在一起排序,每遇到一个间隔的起始值,我们把个数加1,遇到一个结束值,我们把个数减1,这样,我们可以得到最大个数。对于 “点” 的值,它一定是在一个结束值和一个起始值之间。

代码如下:

public class Test {
	/*
	 * start: stores the start value of the intervals;
	 * end: stores the end value of the intervals
	 */
	public float findPoint(float[] start, float[] end) {
		
		int currentInterval = 0;
		int maximumInterval = 0;
		
		float pointBeginValue = 0.0f;
		float pointValue = 0.0f;
		//store the interval start values into the list
		ArrayList<Point> list = new ArrayList<Point>();
		for (int i = 0; i < start.length; i++) {
			list.add(new Point(start[i], true));
		}
		//store the interval end values into the list
		for (int j = 0; j < end.length; j++) {
			list.add(new Point(end[j], false));
		}
		//sort
		Collections.sort(list);
		
		for (int i = 0; i < list.size(); i++) {
			if (list.get(i).bStart) {
				currentInterval++;
				if (currentInterval >= maximumInterval) {
					maximumInterval = currentInterval;
					pointBeginValue = list.get(i).value;
				}
			} else {
				if (currentInterval == maximumInterval) {
					pointValue = (pointBeginValue + list.get(i).value) / 2.0f;
				}
				currentInterval--;
			}				
		}
		return pointValue;
	}
	
	public static void main(String[] args) {
		//start value of the interval
		float[] start = {1.2f, 3, 5, 1, 2.4f};
		//end value of the interval
		float[] end = {2.3f, 4.5f, 7.9f, 2, 4};
		System.out.println(new Test().findPoint(start, end));
	}
}

class Point implements Comparable<Point>{
	float value = 0.0f;
	boolean bStart = false;
	
	Point(float value, boolean bStart) {
		this.value = value;
		this.bStart = bStart;
	}

	public int compareTo(Point o) {
		if (value > ((Point)o).value ) {
				return 1;
		} else if (value == ((Point)o).value) {
				return 0;
		}
		return -1;
	}
}
参考: http://haixiaoyang.wordpress.com/2012/03/19/find-the-point-intersect-with-most-intervals/

转载请注明出处:http://blog.youkuaiyun.com/beiyeqingteng


2025-11-05 09:58:32.567 24027-24027 MediaCodecList com.tencent.yolov5ncnn D codecHandlesFormat: no format, so no extra checks 2025-11-05 09:58:32.572 24027-24085 CCodec com.tencent.yolov5ncnn D allocate(c2.android.avc.encoder) 2025-11-05 09:58:32.576 24027-24085 CCodec com.tencent.yolov5ncnn I setting up &#39;default&#39; as default (vendor) store 2025-11-05 09:58:32.587 24027-24085 CCodec com.tencent.yolov5ncnn I Created component [c2.android.avc.encoder] for [c2.android.avc.encoder] 2025-11-05 09:58:32.590 24027-24085 CCodecConfig com.tencent.yolov5ncnn D read media type: video/avc 2025-11-05 09:58:32.600 24027-24085 ReflectedParamUpdater com.tencent.yolov5ncnn D extent() != 1 for single value type: algo.buffers.max-count.values 2025-11-05 09:58:32.601 24027-24085 ReflectedParamUpdater com.tencent.yolov5ncnn D extent() != 1 for single value type: output.subscribed-indices.values 2025-11-05 09:58:32.603 24027-24085 ReflectedParamUpdater com.tencent.yolov5ncnn D extent() != 1 for single value type: input.buffers.allocator-ids.values 2025-11-05 09:58:32.606 24027-24085 ReflectedParamUpdater com.tencent.yolov5ncnn D extent() != 1 for single value type: output.buffers.allocator-ids.values 2025-11-05 09:58:32.608 24027-24085 ReflectedParamUpdater com.tencent.yolov5ncnn D extent() != 1 for single value type: algo.buffers.allocator-ids.values 2025-11-05 09:58:32.611 24027-24085 ReflectedParamUpdater com.tencent.yolov5ncnn D extent() != 1 for single value type: output.buffers.pool-ids.values 2025-11-05 09:58:32.612 24027-24085 ReflectedParamUpdater com.tencent.yolov5ncnn D extent() != 1 for single value type: algo.buffers.pool-ids.values 2025-11-05 09:58:32.626 24027-24085 ReflectedParamUpdater com.tencent.yolov5ncnn D ignored struct field coding.gop.values 2025-11-05 09:58:32.627 24027-24085 ReflectedParamUpdater com.tencent.yolov5ncnn D ignored struct field coding.qp.values 2025-11-05 09:58:32.630 24027-24085 CCodecConfig com.tencent.yolov5ncnn D ignoring local param raw.color (0xc2001809) as it is already supported 2025-11-05 09:58:32.635 24027-24085 CCodecConfig com.tencent.yolov5ncnn I query failed after returning 13 values (BAD_INDEX) 2025-11-05 09:58:32.636 24027-24085 CCodecConfig com.tencent.yolov5ncnn D c2 config diff is Dict { c2::u32 algo.bitrate-mode.value = 3 c2::i32 coded.average-qp.value = 0 c2::u32 coded.bitrate.value = 64000 c2::float coded.frame-rate.value = 1 c2::u32 coded.picture-type.value = 0 c2::u32 coded.pl.level = 20492 c2::u32 coded.pl.profile = 20481 c2::u32 coded.vui.color.matrix = 0 c2::u32 coded.vui.color.primaries = 0 c2::u32 coded.vui.color.range = 0 c2::u32 coded.vui.color.transfer = 0 c2::u32 coding.intra-refresh.mode = 0 c2::float coding.intra-refresh.period = 0 c2::u32 coding.request-sync-frame.value = 0 c2::i64 coding.sync-frame-interval.value = 1000000 c2::u32 input.delay.value = 0 string input.media-type.value = "video/raw" string output.media-type.value = "video/avc" c2::u32 raw.color.matrix = 0 c2::u32 raw.color.primaries = 0 c2::u32 raw.color.range = 0 c2::u32 raw.color.transfer = 0 c2::u32 raw.size.height = 16 c2::u32 raw.size.width = 16 } 2025-11-05 09:58:32.636 24027-24085 ColorUtils com.tencent.yolov5ncnn W expected specified color aspects (0:0:0:0) 2025-11-05 09:58:32.643 24027-24027 MediaCodec com.tencent.yolov5ncnn E Media Quality Service not found. 2025-11-05 09:58:32.650 24027-24027 CodecSeeding com.tencent.yolov5ncnn D Seed: codec c2.android.avc.encoder, mediatype video/avc, overrideable 1 2025-11-05 09:58:32.650 24027-24027 CodecProperties com.tencent.yolov5ncnn D setTuningValue(vq-target-bpp,0) 2025-11-05 09:58:32.650 24027-24027 CodecProperties com.tencent.yolov5ncnn D setTuningValue(vq-target-bpp-1080p,1.90) 2025-11-05 09:58:32.650 24027-24027 CodecProperties com.tencent.yolov5ncnn D setTuningValue(vq-target-bpp-720p,2.25) 2025-11-05 09:58:32.650 24027-24027 CodecProperties com.tencent.yolov5ncnn D setTuningValue(vq-target-bpp-540p,2.65) 2025-11-05 09:58:32.650 24027-24027 CodecProperties com.tencent.yolov5ncnn D setTuningValue(vq-target-bpp-480p,3.00) 2025-11-05 09:58:32.650 24027-24027 CodecProperties com.tencent.yolov5ncnn D setTuningValue(vq-target-bpp-320x240,0) 2025-11-05 09:58:32.650 24027-24027 CodecProperties com.tencent.yolov5ncnn D setTuningValue(vq-target-qpmax,-1) 2025-11-05 09:58:32.650 24027-24027 CodecProperties com.tencent.yolov5ncnn D setTuningValue(vq-target-qpmax-1080p,45) 2025-11-05 09:58:32.650 24027-24027 CodecProperties com.tencent.yolov5ncnn D setTuningValue(vq-target-qpmax-720p,43) 2025-11-05 09:58:32.650 24027-24027 CodecProperties com.tencent.yolov5ncnn D setTuningValue(vq-target-qpmax-540p,42) 2025-11-05 09:58:32.650 24027-24027 CodecProperties com.tencent.yolov5ncnn D setTuningValue(vq-target-qpmax-480p,38) 2025-11-05 09:58:32.650 24027-24027 CodecProperties com.tencent.yolov5ncnn D setTuningValue(vq-bitrate-phaseout,1.75) 2025-11-05 09:58:32.650 24027-24027 CodecProperties com.tencent.yolov5ncnn D setTuningValue(vq-boost-missing-qp,0.20) 2025-11-05 09:58:32.650 24027-24027 CodecProperties com.tencent.yolov5ncnn D setFeatureValue(intra-refresh,0) 2025-11-05 09:58:32.650 24027-24027 CodecProperties com.tencent.yolov5ncnn D setFeatureValue(qp-bounds,0) 2025-11-05 09:58:32.651 24027-24027 CodecProperties com.tencent.yolov5ncnn D setFeatureValue(_vq_eligible.device,1) 2025-11-05 09:58:32.651 24027-24027 CodecProperties com.tencent.yolov5ncnn D setFeatureValue(_quality.target,1) 2025-11-05 09:58:32.651 24027-24027 CodecSeeding com.tencent.yolov5ncnn D Seed: codec c2.android.avc.encoder, mediatype video/avc, overrideable 0 2025-11-05 09:58:32.651 24027-24027 MediaCodec com.tencent.yolov5ncnn D shapeMediaFormat: deltas(1): AMessage(what = 0x00000000) = { int32_t android._encoding-quality-level = 0 } 2025-11-05 09:58:32.654 24027-24085 CCodec com.tencent.yolov5ncnn D [c2.android.avc.encoder] buffers are bound to CCodec for this session 2025-11-05 09:58:32.655 24027-24085 CCodecConfig com.tencent.yolov5ncnn D no c2 equivalents for color-format 2025-11-05 09:58:32.655 24027-24085 CCodecConfig com.tencent.yolov5ncnn D no c2 equivalents for flags 2025-11-05 09:58:32.655 24027-24085 CCodecConfig com.tencent.yolov5ncnn D no c2 equivalents for encoder 2025-11-05 09:58:32.663 24027-24085 CCodecConfig com.tencent.yolov5ncnn D c2 config diff is c2::u32 coded.bitrate.value = 3732480 c2::float coded.frame-rate.value = 15 c2::u32 raw.size.height = 648 c2::u32 raw.size.width = 1152 2025-11-05 09:58:32.664 24027-24085 ColorUtils com.tencent.yolov5ncnn W expected specified color aspects (0:0:0:0) 2025-11-05 09:58:32.672 24027-24085 BufferPoolAccessor2.0 com.tencent.yolov5ncnn D Destruction - bufferpool2 0x73cf1889f178 cached: 0/0M, 0/0% in use; allocs: 1, 0% recycled; transfers: 0, 0% unfetched 2025-11-05 09:58:32.672 24027-24085 CCodec com.tencent.yolov5ncnn D encoding statistics level = 0 2025-11-05 09:58:32.672 24027-24085 CCodec com.tencent.yolov5ncnn D setup formats input: AMessage(what = 0x00000000) = { Rect crop(0, 0, 1151, 647) int32_t color-standard = 0 int32_t color-range = 0 int32_t color-transfer = 0 int32_t frame-rate = 15 int32_t height = 648 int32_t intra-refresh-period = 0 string mime = "video/raw" int32_t video-qp-average = 0 int32_t width = 1152 int32_t android._dataspace = 0 int32_t using-sw-read-often = 1 int64_t android._C2MemoryUsage = 1 int32_t color-format = 21 int32_t android._color-format = 21 int32_t stride = 1152 int32_t slice-height = 648 } 2025-11-05 09:58:32.672 24027-24085 CCodec com.tencent.yolov5ncnn D setup formats output: AMessage(what = 0x00000000) = { int32_t bitrate = 3732480 int32_t bitrate-mode = 1 Rect crop(0, 0, 1151, 647) int32_t color-standard = 0 int32_t color-range = 0 int32_t color-transfer = 0 int32_t frame-rate = 15 int32_t height = 648 int32_t intra-refresh-period = 0 int32_t level = 4096 int32_t max-bitrate = 3732480 string mime = "video/avc" int32_t profile = 65536 int32_t video-qp-average = 0 int32_t width = 1152 } 2025-11-05 09:58:32.673 24027-24085 CCodecConfig com.tencent.yolov5ncnn I query failed after returning 14 values (BAD_INDEX) 2025-11-05 09:58:32.674 24027-24085 cent.yolov5ncnn com.tencent.yolov5ncnn E Failed to query component interface for required system resources: 6 2025-11-05 09:58:32.679 24027-24085 Codec2Client com.tencent.yolov5ncnn W query -- param skipped: index = 1342179345. 2025-11-05 09:58:32.679 24027-24085 Codec2Client com.tencent.yolov5ncnn W query -- param skipped: index = 2415921170. 2025-11-05 09:58:32.682 24027-24085 CCodecBufferChannel com.tencent.yolov5ncnn D [c2.android.avc.encoder#579] Using basic input block pool with poolID 1 => got 1 - OK (0) 2025-11-05 09:58:32.685 24027-24085 CCodecBufferChannel com.tencent.yolov5ncnn I [c2.android.avc.encoder#579] Created output block pool with allocatorID 16 => poolID 150 - OK 2025-11-05 09:58:32.686 24027-24085 CCodecBufferChannel com.tencent.yolov5ncnn D [c2.android.avc.encoder#579] Configured output block pool ids 150 => OK 2025-11-05 09:58:32.691 24027-24085 CCodecBuffers com.tencent.yolov5ncnn D [c2.android.avc.encoder#579:2D-BB-Input] updating image-data 2025-11-05 09:58:32.691 24027-24085 CCodecBuffers com.tencent.yolov5ncnn D [c2.android.avc.encoder#579:2D-BB-Input] updating stride = 1152, width: 1152, height: 648 2025-11-05 09:58:32.691 24027-24085 CCodecBuffers com.tencent.yolov5ncnn D [c2.android.avc.encoder#579:2D-BB-Input] updating vstride = 648 2025-11-05 09:58:32.756 24027-24027 MPEG4Writer com.tencent.yolov5ncnn D fpathconf _PC_FILESIZEBITS:64 2025-11-05 09:58:32.756 24027-24027 MPEG4Writer com.tencent.yolov5ncnn D File size limit set to 4503599627370495 bytes implicitly 2025-11-05 09:58:32.756 24027-24027 MPEG4Writer com.tencent.yolov5ncnn D MP4WtrCtrlHlpLooper Started 2025-11-05 09:58:32.758 24027-24027 MPEG4Writer com.tencent.yolov5ncnn I limits: 4503599627370495/0 bytes/us, bit rate: -1 bps and the estimated moov size 3192 bytes
最新发布
11-06
<think>我们分析日志中的关键错误信息: 1. `Failed to query component interface for required system resources: 6` 这表示在初始化编码器时,查询系统资源失败,错误代码6(可能对应`C2_NO_MEMORY`或其他资源不足错误)。 2. 在配置编码器参数时出现多次警告,如`ColorUtils W expected specified color aspects (0:0:0:0)`,表明颜色参数设置可能不标准。 3. 日志中显示编码器配置了较小的分辨率(1152x648)和帧率(15fps),以及比特率(3732480 bps ≈ 3.7 Mbps),这些参数在大多数设备上应该是可行的,但错误可能源于设备资源不足或编码器不支持特定配置。 可能的原因: - 设备上的硬件编码器资源已被其他应用占用。 - 编码器无法满足当前配置(例如,设备不支持该分辨率或帧率下的编码)。 - 内存不足,无法为编码器分配所需资源。 解决方案: 1. 检查设备是否支持当前配置:在初始化编码器前,通过`MediaCodecList`和`MediaCodecInfo`检查编码器能力。 2. 捕获初始化异常,并在资源不足时尝试使用软件编码器。 3. 调整视频编码参数(如降低分辨率、比特率或帧率)以减轻资源压力。 代码示例:安全初始化MediaCodec编码器 步骤: 1. 遍历设备支持的编码器,选择支持所需MIME类型(如H.264)的编码器。 2. 检查编码器是否支持指定的配置(分辨率、帧率等)。 3. 如果硬件编码器初始化失败,尝试使用软件编码器。 示例代码: ```java public class VideoEncoder { private static final String MIME_TYPE = "video/avc"; // H.264 private MediaCodec mediaCodec; private boolean useSoftwareEncoder = false; public void initEncoder(int width, int height, int bitrate, int frameRate) throws IOException { // 尝试硬件编码器 try { mediaCodec = MediaCodec.createEncoderByType(MIME_TYPE); } catch (IOException e) { // 硬件编码器失败,尝试软件编码器 useSoftwareEncoder = true; mediaCodec = createSoftwareEncoder(); } // 配置参数 MediaFormat format = MediaFormat.createVideoFormat(MIME_TYPE, width, height); format.setInteger(MediaFormat.KEY_BIT_RATE, bitrate); format.setInteger(MediaFormat.KEY_FRAME_RATE, frameRate); format.setInteger(MediaFormat.KEY_COLOR_FORMAT, MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface); format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 1); // 关键帧间隔(秒) try { mediaCodec.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE); } catch (MediaCodec.CodecException e) { // 如果配置失败,尝试使用更低的配置 if (e.getErrorCode() == MediaCodec.CodecException.ERROR_INSUFFICIENT_RESOURCE) { // 降低分辨率再试 width /= 2; height /= 2; format.setInteger(MediaFormat.KEY_WIDTH, width); format.setInteger(MediaFormat.KEY_HEIGHT, height); mediaCodec.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE); } else { throw e; } } // 启动编码器 mediaCodec.start(); } private MediaCodec createSoftwareEncoder() throws IOException { // 查找软件编码器 MediaCodecList codecList = new MediaCodecList(MediaCodecList.ALL_CODECS); for (MediaCodecInfo codecInfo : codecList.getCodecInfos()) { if (!codecInfo.isEncoder()) continue; for (String type : codecInfo.getSupportedTypes()) { if (type.equals(MIME_TYPE) && codecInfo.getName().toLowerCase().contains("omx.google")) { // 使用软件编码器(通常以OMX.google开头) return MediaCodec.createByCodecName(codecInfo.getName()); } } } throw new IOException("No software encoder found for " + MIME_TYPE); } // 其他方法:输入数据、获取输出数据等 } ``` 关键点解释: 1. **硬件编码器优先**:首先尝试使用默认的硬件编码器,因为硬件编码器更高效。 2. **软件编码器回退**:当硬件编码器不可用时,显式查找并使用软件编码器(通常以"OMX.google"开头)。 3. **配置降级**:如果配置失败且错误原因为资源不足,尝试降低分辨率再次配置。 4. **错误代码处理**:捕获`CodecException`并根据错误代码(如`ERROR_INSUFFICIENT_RESOURCE`)采取相应措施。 注意事项: - 降低分辨率可能会导致视频质量下降,但可以保证编码器正常工作。 - 软件编码器虽然兼容性好,但性能较差,可能导致编码延迟或高CPU占用。 此外,日志中出现的`Media Quality Service not found`警告通常可以忽略,不影响基本功能。 针对日志中颜色参数警告,可以尝试明确设置颜色格式: ```java format.setInteger(MediaFormat.KEY_COLOR_FORMAT, MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420Flexible); ``` 如果设备支持`COLOR_FormatYUV420Flexible`,则可以避免颜色格式不匹配问题。 最后,资源查询失败(错误6)可能是暂时性的,可以尝试重新初始化编码器。 如果问题仍然存在,考虑在初始化前释放其他资源(如相机预览),确保编码器有足够的内存。 --- §§相关问题§§: 1. 如何在Android中检查MediaCodec是否支持特定的视频编码配置? 2. MediaCodec初始化时出现CodecException的常见原因有哪些? 3. 如何在Android视频编码中正确设置颜色格式以避免警告? 4. 硬件编码器和软件编码器在性能上有什么差异? </think>### 问题分析 日志中的核心错误是:`Failed to query component interface for required system resources: 6`(错误代码6),这表明在使用 Android MediaCodec API 初始化 H.264 编码器时,系统资源查询失败。关键日志点包括: 1. **编码器初始化失败**:`CCodec` 组件在创建 H.264 编码器时无法获取所需资源 2. **颜色格式警告**:`ColorUtils W expected specified color aspects (0:0:0:0)` 表示颜色参数未正确配置 3. **参数设置异常**:多次出现 `extent() != 1 for single value type` 表明参数格式不匹配 4. **分辨率问题**:原始配置尝试使用 1152x648 分辨率,但日志显示实际处理为 16x16 的无效尺寸 --- ### 解决方法 #### 核心修复方案 1. **验证设备编码能力**:在初始化前检查设备是否支持目标编码配置 2. **正确配置颜色格式**:明确设置 `COLOR_FormatYUV420Flexible` 3. **处理资源获取异常**:捕获 `MediaCodec.CodecException` 并提供备选方案 4. **修复分辨率参数**:确保输入尺寸与 Surface 匹配 #### 完整代码实现 ```java public class H264Encoder { private static final String MIME_TYPE = "video/avc"; // H.264 private MediaCodec mediaCodec; private Surface inputSurface; public void initEncoder(int width, int height, int bitrate, int frameRate) { // 1. 检查编码能力 if (!isEncodingSupported(width, height)) { throw new UnsupportedOperationException("Unsupported encoding parameters"); } try { // 2. 创建编码器实例 mediaCodec = MediaCodec.createEncoderByType(MIME_TYPE); // 3. 配置编码参数(关键修复点) MediaFormat format = MediaFormat.createVideoFormat(MIME_TYPE, width, height); format.setInteger(MediaFormat.KEY_BIT_RATE, bitrate); format.setInteger(MediaFormat.KEY_FRAME_RATE, frameRate); format.setInteger(MediaFormat.KEY_COLOR_FORMAT, MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420Flexible); // 修复颜色格式警告 format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 1); // 关键帧间隔 // 4. 配置编码器 mediaCodec.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE); // 5. 创建输入Surface inputSurface = mediaCodec.createInputSurface(); mediaCodec.start(); } catch (IOException | MediaCodec.CodecException e) { handleCodecException(e, width, height); // 异常处理 } } private boolean isEncodingSupported(int width, int height) { MediaCodecList codecList = new MediaCodecList(MediaCodecList.ALL_CODECS); for (MediaCodecInfo info : codecList.getCodecInfos()) { if (!info.isEncoder()) continue; for (String type : info.getSupportedTypes()) { if (type.equalsIgnoreCase(MIME_TYPE)) { MediaCodecInfo.CodecCapabilities caps = info.getCapabilitiesForType(type); // 检查分辨率支持 MediaCodecInfo.VideoCapabilities videoCaps = caps.getVideoCapabilities(); if (!videoCaps.isSizeSupported(width, height)) { Log.w("Encoder", "Unsupported resolution: " + width + "x" + height); return false; } // 检查颜色格式支持 int[] colorFormats = caps.colorFormats; for (int format : colorFormats) { if (format == MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420Flexible) { return true; } } } } } return false; } private void handleCodecException(Exception ex, int width, int height) { Log.e("Encoder", "Codec init error: " + ex.getMessage()); // 尝试降低配置 int newWidth = width / 2; int newHeight = height / 2; Log.w("Encoder", "Trying fallback resolution: " + newWidth + "x" + newHeight); initEncoder(newWidth, newHeight, 1500000, 15); // 降级参数 } // 获取编码器Surface(用于Camera2等输入源) public Surface getInputSurface() { return inputSurface; } // 释放资源 public void release() { if (mediaCodec != null) { mediaCodec.stop(); mediaCodec.release(); mediaCodec = null; } } } ``` --- ### 关键问题解析 1. **错误代码6 (C2_NO_MEMORY)** - **原因**:编码器资源分配失败,通常由于: - 分辨率/帧率超出硬件支持范围 - 同时运行的编码器实例过多 - 内存碎片化严重 - **解决方案**:通过 `isEncodingSupported()` 预检设备能力 2. **颜色格式警告 (0:0:0:0)** - **原因**:未明确指定 YUV 颜色空间参数 - **修复**:设置 `COLOR_FormatYUV420Flexible`(Android 5.0+ 通用格式) 3. **分辨率配置错误** - **日志证据**: ``` c2::u32 raw.size.height = 16 c2::u32 raw.size.width = 16 ``` - **原因**:输入Surface与配置尺寸不匹配 - **修复**:确保 Camera/OpenGL 输出尺寸与 `createVideoFormat()` 参数一致 4. **参数格式不匹配** - **日志证据**:`extent() != 1 for single value type` - **原因**:传递给编码器的参数维度错误(如应为单值却传入数组) - **修复**:使用 MediaFormat 的规范API设置参数 --- ### 最佳实践建议 1. **分辨率适配策略**: ```java // 选择设备支持的最佳分辨率 MediaCodecInfo.VideoCapabilities videoCaps = ...; List<Size> supportedSizes = new ArrayList<>(); for (Size size : Arrays.asList( new Size(1920, 1080), new Size(1280, 720), new Size(864, 480)) ) { if (videoCaps.isSizeSupported(size.getWidth(), size.getHeight())) { supportedSizes.add(size); } } Collections.sort(supportedSizes, (a, b) -> Integer.compare(b.getWidth() * b.getHeight(), a.getWidth() * a.getHeight())); Size selectedSize = supportedSizes.get(0); // 选择最大支持分辨率 ``` 2. **异常处理增强**: ```java try { mediaCodec.configure(...); } catch (MediaCodec.CodecException e) { if (e.getErrorCode() == MediaCodec.CodecException.ERROR_INSUFFICIENT_RESOURCE) { // 设备资源不足的处理逻辑 } else if (e.getDiagnosticInfo().contains("Unsupported")) { // 参数不支持的处理逻辑 } } ``` 3. **颜色空间兼容处理**: ```java // 回退到基本YUV格式 format.setInteger(MediaFormat.KEY_COLOR_FORMAT, MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420SemiPlanar); ``` ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值