【发布时间】:2018-08-30 03:28:21
【问题描述】:
我正在开发一个视频/照片处理库(添加 Instagram/Snapchat 等过滤器)。到目前为止,核心功能运行良好。
但是,我发现视频处理(重新编码输入视频)非常令人沮丧。似乎有许多边缘情况和特定于设备的问题会阻止库 100% 的工作。
我想知道如何选择/创建适用于设备的 MediaFormat。
目前,我正在设置用于对视频进行编码的 MediaFormat,如下所示:
// assume that "extractor" is a media extractor wrapper, which holds a
// reference to the MediaFormat of the input video
fun getOutputVideoFormat(): MediaFormat {
val mimeType = MediaFormat.MIMETYPE_VIDEO_H263
var width = -1
var height = -1
var frameRate = 30
var bitrate = 10_000_000
val colorFormat = MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface
if (extractor.videoFormat.containsKey(MediaFormat.KEY_WIDTH)) {
width = extractor.videoFormat.getInteger(MediaFormat.KEY_WIDTH)
}
if (extractor.videoFormat.containsKey(MediaFormat.KEY_HEIGHT)) {
height = extractor.videoFormat.getInteger(MediaFormat.KEY_HEIGHT)
}
if(extractor.videoFormat.containsKey(MediaFormat.KEY_FRAME_RATE)){
frameRate = extractor.videoFormat.getInteger(MediaFormat.KEY_FRAME_RATE)
}
if(extractor.videoFormat.containsKey(MediaFormat.KEY_BIT_RATE)){
bitrate = extractor.videoFormat.getInteger(MediaFormat.KEY_BIT_RATE)
}
val format = MediaFormat.createVideoFormat(mimeType, width, height)
format.setInteger(MediaFormat.KEY_COLOR_FORMAT, colorFormat)
format.setInteger(MediaFormat.KEY_BIT_RATE, bitrate)
format.setInteger(MediaFormat.KEY_FRAME_RATE, frameRate)
format.setInteger(MediaFormat.KEY_CAPTURE_RATE, frameRate)
// prevent crash on some Samsung devices
// http://stackoverflow.com/questions/21284874/illegal-state-exception-when-calling-mediacodec-configure?answertab=votes#tab-top
format.setInteger(MediaFormat.KEY_MAX_INPUT_SIZE, width * height)
format.setInteger(MediaFormat.KEY_MAX_WIDTH, width)
format.setInteger(MediaFormat.KEY_MAX_HEIGHT, height)
format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 0)
return format
}
到目前为止,这适用于我测试过的所有主要设备,但据报道,三星 A5 等一些设备在使用这种格式时会静默失败,并且只是使用正常工作的输入视频创建损坏的输出视频在所有其他设备上。
如何判断 MediaFormat 是否真的会在给定设备上成功?
我从三星 A5 设备获得的唯一日志表明,当 MediaCodec 通过“INFO_OUTPUT_FORMAT_CHANGED”信号发送时,返回以下媒体格式:
csd-1=java.nio.ByteArrayBuffer[position=0,limit=8,capacity=8],
mime=video/avc,
frame-rate=30,
remained_resource=2549760,
height=480,
width=480,
max_capacity=3010560, what=1869968451,
bitrate=10000000,
csd-0=java.nio.ByteArrayBuffer[position=0,limit=17,capacity=17]
考虑到输入视频的分辨率为 1280x720,这种格式对我来说似乎无效
【问题讨论】:
标签: android video-processing android-mediacodec