文章目录
前言
应用层设置音视频参数
基础参数
- videoFrameHeight
- videoFrameWidth
- videoFrameRate
- videoBitRate
- audioBitRate
- audioChannels
- audioSampleRate
编解码相关参数
- AudioSource
- VideoSource
- OutputFormat
- VideoEncoder
- AudioEncoder
- CaptureRate
- VideoFrameRate
- VideoEncodingBitRate
1 视频参数
1.1 videosize——图像图像分辨率
videoFrameHeight
videoFrameWidth
视频图像的size,长宽是多少像素点
常见的有1920*1080
mMediaRecorder.setVideoSize(mProfile.videoFrameHeight, mProfile.videoFrameWidth);
//log
//07-28 03:44:24.025 14402 14402 V MediaRecorder: setVideoSize(1920, 1080)
//mediacodec.xml配置(OMX.qcom.video.encoder.hevc为例)
<Limit name="size" min="176x64" max="3840x2160" />
1.2 videoFrameRate——视频帧率
视频的帧率,即1s有多少张图像
例如部分电影采用的是24帧。
mMediaRecorder.setVideoFrameRate(mProfile.videoFrameRate);
//log
//07-28 03:44:24.024 14402 14402 V MediaRecorder: setVideoFrameRate(30)
1.3 videoBitRate——视频码率
视频码率计算公式:码率=帧率 * 长 * 宽 * 像素点数据大小
存疑为什么是20000000整数
计算
bitrate=30 * 1920 * 1080 * X = 62208000 * X
那么X 约为 0.032
存疑
mMediaRecorder.setVideoEncodingBitRate(mProfile.videoBitRate);
//log
//07-28 03:44:05.125 14402 14402 V MediaRecorder: setParameters(video-param-encoding-bitrate=20000000)
//mediacodec.xml配置(OMX.qcom.video.encoder.hevc为例)
<Limit name="bitrate" range="1-100000000" />
1.4 videoEncode——视频编码类型
这个参数是app有选项可以设置的,目前app支持h264/h265/mpeg4
mMediaRecorder.setVideoEncoder(mVideoEncoder);
//log
//07-28 03:44:44.465 14402 14402 V MediaRecorder: setVideoEncoder(5)
//数值5的由来,mediarecorder.h
enum video_encoder {
VIDEO_ENCODER_DEFAULT = 0,
VIDEO_ENCODER_H263 = 1,
VIDEO_ENCODER_H264 = 2,
VIDEO_ENCODER_MPEG_4_SP = 3,
VIDEO_ENCODER_VP8 = 4,
VIDEO_ENCODER_HEVC = 5,
VIDEO_ENCODER_LIST_END // must be the last - used to validate the video encoder type
};
//mediacodec.xml配置(OMX.qcom.video.encoder.hevc为例)
<MediaCodec name="OMX.qcom.video.encoder.hevc" type="video/hevc" >
//--------------------------------
补充:
后续会直接获取当前设备加载的encoder类型,数据来源是mediaprofile.xml,该文件定义了支持的视频编码支持列表。
<!-- mediaprofile.xml配置,以h265(hevc)为例 -->
<VideoEncoderCap name="hevc" enabled="true"
minBitRate="64000" maxBitRate="100000000"
minFrameWidth="176" maxFrameWidth="4096"
minFrameHeight="144" maxFrameHeight="2160"
minFrameRate="15" maxFrameRate="30"
maxHFRFrameWidth="0" maxHFRFrameHeight="0"
maxHFRMode="0" />
//--------------------------------
1.5 log
07-28 03:44:44.489 945 15776 V ACodec : [OMX.qcom.video.encoder.hevc] Now Loaded
07-28 03:44:44.491 945 2980 V MediaCodecSource: output format is 'AMessage(what = 0x00000000) = {
07-28 03:44:44.491 945 2980 V MediaCodecSource: string mime = "video/hevc"
07-28 03:44:44.491 945 2980 V MediaCodecSource: int32_t width = 1920
07-28 03:44:44.491 945 2980 V MediaCodecSource: int32_t height = 1080
07-28 03:44:44.491 945 2980 V MediaCodecSource: int32_t stride = 1920
07-28 03:44:44.491 945 2980 V MediaCodecSource: int32_t slice-height = 1080
07-28 03:44:44.491 945 2980 V MediaCodecSource: int32_t color-format = 2130708361
07-28 03:44:44.491 945 2980 V MediaCodecSource: int32_t bitrate = 20000000
07-28 03:44:44.491 945 2980 V MediaCodecSource: int32_t frame-rate = 30
07-28 03:44:44.491 945 2980 V MediaCodecSource: int32_t i-frame-interval = 1
07-28 03:44:44.491 945 2980 V MediaCodecSource: int32_t priority = 0
07-28 03:44:44.491 945 2980 V MediaCodecSource: int32_t feature-nal-length-bitstream = 1
07-28 03:44:44.491 945 2980 V MediaCodecSource: int32_t nal-length-in-bytes = 4
07-28 03:44:44.491 945 2980 V MediaCodecSource: int32_t isNativeRecorder = 1
07-28 03:44:44.491 945 2980 V MediaCodecSource: int32_t create-input-buffers-suspended = 1
07-28 03:44:44.491 945 2980 V MediaCodecSource: }'
07-28 03:44:44.536 945 15775 V MediaCodec: [OMX.qcom.video.encoder.hevc] input surface created as input format: AMessage(what = 0x00000000) = {
07-28 03:44:44.536 945 15775 V MediaCodec: string mime = "video/raw"
07-28 03:44:44.536 945 15775 V MediaCodec: int32_t stride = 1920
07-28 03:44:44.536 945 15775 V MediaCodec: int32_t slice-height = 1080
07-28 03:44:44.536 945 15775 V MediaCodec: int32_t color-format = 2130708361
07-28 03:44:44.536 945 15775 V MediaCodec: int32_t color-range = 2
07-28 03:44:44.536 945 15775 V MediaCodec: int32_t color-standard = 1
07-28 03:44:44.536 945 15775 V MediaCodec: int32_t color-transfer = 3
07-28 03:44:44.536 945 15775 V MediaCodec: int32_t width = 1920
07-28 03:44:44.536 945 15775 V MediaCodec: int32_t height = 1080
07-28 03:44:44.536 945 15775 V MediaCodec: int32_t android._dataspace = 260
07-28 03:44:44.536 945 15775 V MediaCodec: Buffer android._color-aspects = {
07-28 03:44:44.536 945 15775 V MediaCodec: 00000000: 02 00 00 00 01 00 00 00 03 00 00 00 01 00 00 00 ................
07-28 03:44:44.536 945 15775 V MediaCodec: }
07-28 03:44:44.536 945 15775 V MediaCodec: }, output format: AMessage(what = 0x00000000) = {
07-28 03:44:44.536 945 15775 V MediaCodec: int32_t bitrate = 20000000
07-28 03:44:44.536 945 15775 V MediaCodec: int32_t max-bitrate = 20000000
07-28 03:44:44.536 945 15775 V MediaCodec: int32_t frame-rate = 30
07-28 03:44:44.536 945 15775 V MediaCodec: string mime = "video/hevc"
07-28 03:44:44.536 945 15775 V MediaCodec: int32_t width = 1920
07-28 03:44:44.536 945 15775 V MediaCodec: int32_t height = 1080
07-28 03:44:44.536 945 15775 V MediaCodec: int32_t color-range = 2
07-28 03:44:44.536 945 15775 V MediaCodec: int32_t color-standard = 1
07-28 03:44:44.536 945 15775 V MediaCodec: int32_t color-transfer = 3
07-28 03:44:44.536 945 15775 V MediaCodec: }
07-28 03:44:44.536 945 2980 V MediaCodecSource: setting dataspace 0x104, format 0x22
07-28 03:44:44.537 945 15776 V ACodec : onStart
2 音频参数
<!-- mediaprofile.xml配置,以aac为例 -->
<AudioEncoderCap name="aac" enabled="true"
minBitRate="8000" maxBitRate="96000"
minSampleRate="8000" maxSampleRate="48000"
minChannels="1" maxChannels="6" />
2.1 audioChannels——声道数
声道数: 常见的是左右声道(channel数为2)
mMediaRecorder.setAudioChannels(mProfile.audioChannels);
//log
//07-28 03:44:44.465 14402 14402 V MediaRecorder: setParameters(audio-param-number-of-channels=2)
2.2 audioSampleRate——音频采样率
音频采样率: 是针对模拟信号,一秒采多少次数据
频率:以正弦波为例,1khz的正弦波,1s内存在1000个周期,一个周期包含1个正半周和1个负半周
如图,采样数位48000,正弦波频率为1000,即1周期为48个点,正半周24个,负半周24个。
mMediaRecorder.setAudioSamplingRate(mProfile.audioSampleRate);
//log
//07-28 03:44:44.465 14402 14402 V MediaRecorder: setParameters(audio-param-sampling-rate=48000)
2.3 audioBitRate——音频码率
音频码率计算公式: 码率 = 音频采样率 * 声道数 * 音频位深
音频位深:采样点的幅值转换为二进制数,具体可以查看下pcm编码,常见的是8/16/32进制,注意最高位为符号位,正半周数值范围0-7F,负半轴80-FF。
计算:bitrate = 48000 * 2 * X = 156000
X = 1.625
aac编码进行了压缩,所以平均计算下来一个采样点用了不到2bit数据量。
位深这个变量,以pcm数据格式更方便理解,在native层会强制设置为16bit的pcm格式,而adsp中也会定义dai的format为16bit,这个变量需要从打开pcm设备往后追溯到硬件。
mMediaRecorder.setAudioEncodingBitRate(mProfile.audioBitRate);
//log
//07-28 03:44:44.465 14402 14402 V MediaRecorder: setParameters(audio-param-encoding-bitrate=156000)
//在mediaprofile.xml中定义了audioencoder配置,音频最大码率为96000,所以将app设置的156000降下来
//07-28 03:44:44.556 945 2980 W StagefrightRecorder: Intended audio encoding bit rate (156000) is too large and will be set to (96000)
2.4 audioEncoder——音频编码类型
app设置的,目前有aac和amrnb两种选项。
mMediaRecorder.setAudioEncoder(audioEncoder);
//log
//07-28 03:44:44.465 14402 14402 V MediaRecorder: setAudioEncoder(3)
//数值3的由来,mediarecorder.h
enum audio_encoder {
AUDIO_ENCODER_DEFAULT = 0,
AUDIO_ENCODER_AMR_NB = 1,
AUDIO_ENCODER_AMR_WB = 2,
AUDIO_ENCODER_AAC = 3,
AUDIO_ENCODER_HE_AAC = 4,
AUDIO_ENCODER_AAC_ELD = 5,
AUDIO_ENCODER_VORBIS = 6,
AUDIO_ENCODER_OPUS = 7,
AUDIO_ENCODER_EVRC = 10,
AUDIO_ENCODER_QCELP = 11,
AUDIO_ENCODER_LPCM = 12,
AUDIO_ENCODER_MPEGH = 13,
AUDIO_ENCODER_LIST_END // must be the last - used to validate the audio encoder type
};
//(OMX.qcom.audio.encoder.aac为例)
//未找到该类型在xml中定义,但是确实是支持的,
//qc_omx_core.h中只有定义该名字
根据log来看,该编码器的typec应该是audio/mp4a-latm
07-28 03:44:44.660 945 2980 V MediaCodecSource: output format is 'AMessage(what = 0x00000000) = {
07-28 03:44:44.660 945 2980 V MediaCodecSource: string mime = "audio/mp4a-latm"
07-28 03:44:44.660 945 2980 V MediaCodecSource: int32_t aac-profile = 2
07-28 03:44:44.660 945 2980 V MediaCodecSource: int32_t max-input-size = 2048
07-28 03:44:44.660 945 2980 V MediaCodecSource: int32_t channel-count = 2
07-28 03:44:44.660 945 2980 V MediaCodecSource: int32_t sample-rate = 48000
07-28 03:44:44.660 945 2980 V MediaCodecSource: int32_t bitrate = 96000
07-28 03:44:44.660 945 2980 V MediaCodecSource: int32_t priority = 0
07-28 03:44:44.660 945 2980 V MediaCodecSource: }'
07-28 03:44:44.664 945 15783 V MediaCodec: [OMX.qcom.audio.encoder.aac] configured as input format: AMessage(what = 0x00000000) = {
07-28 03:44:44.664 945 15783 V MediaCodec: string mime = "audio/raw"
07-28 03:44:44.664 945 15783 V MediaCodec: int32_t channel-count = 2
07-28 03:44:44.664 945 15783 V MediaCodec: int32_t sample-rate = 48000
07-28 03:44:44.664 945 15783 V MediaCodec: int32_t pcm-encoding = 2
07-28 03:44:44.664 945 15783 V MediaCodec: }, output format: AMessage(what = 0x00000000) = {
07-28 03:44:44.664 945 15783 V MediaCodec: int32_t bitrate = 96000
07-28 03:44:44.664 945 15783 V MediaCodec: int32_t max-bitrate = 96000
07-28 03:44:44.664 945 15783 V MediaCodec: string mime = "audio/mp4a-latm"
07-28 03:44:44.664 945 15783 V MediaCodec: int32_t channel-count = 2
07-28 03:44:44.664 945 15783 V MediaCodec: int32_t sample-rate = 48000
07-28 03:44:44.664 945 15783 V MediaCodec: }
07-28 03:44:44.665 945 2980 V MediaCodecSource: setting dataspace 0x10c10000, format 0x22
07-28 03:44:44.665 945 15783 V ACodec : onStart