Android 音视频笔记3:MediaCodec 笔记01

0X00 MediaCodec

1.MediaCodec 的两种编码模式:

ByteBuffer 模式:
格式:COLOR_FORMAT 对应的值是 MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420SemiPlanar(图像格式 NV21,也可能是其他的需要一一对应)。
操作:通过 MediaCodec.dequeueInputBuffer() 获取数据输入缓冲区,再通过 MediaCodec.queueInputBuffer() 手动将 YUV 图像传给 MediaCodec。
Surface 模式:
格式:COLOR_FORMAT 对应的值是 MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface。
操作:通过 MediaCodec.createInputSurface() 创建编码数据源 Surface,再通过 OpenGL 纹理,将相机预览图像绘制到该 Surface 上。

2.MediaCodec 参数

    String codecName = MediaFormat.MIMETYPE_VIDEO_AVC;
    int colorFormat = MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420Planar;

    MediaFormat encodeMediaFormat = MediaFormat.createVideoFormat(codecName, width, height);
    encodeMediaFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT, colorFormat);
    encodeMediaFormat.setInteger(MediaFormat.KEY_BIT_RATE, 2500000);
    encodeMediaFormat.setInteger(MediaFormat.KEY_FRAME_RATE, 30);
    encodeMediaFormat.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 1);
    encodeMediaFormat.setInteger(MediaFormat.KEY_BITRATE_MODE, MediaCodecInfo.EncoderCapabilities.BITRATE_MODE_VBR);
    MediaCodec encodeCodec = MediaCodec.createByCodecName(codecName);
    encodeCodec.configure(encodeMediaFormat, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
    encodeCodec.start();

KEY_COLOR_FORMAT, 编码前源颜色格式
KEY_BIT_RATE, 比特率越高,每秒传送数据就越多,画质就越清晰,视频文件占用空间也越大。
KEY_FRAME_RATE, 帧率,视频每秒传输的帧数(画面数),每秒帧数越多,显示的画面就越流畅,但是码率恒定帧率增加,画质则会降低。
KEY_I_FRAME_INTERVAL 关键帧间隔

android.media.MediaCodec$CodecException错误。

0x01 重点参数解释

KEY_BITRATE_MODE 模式

BITRATE_MODE_CQ
忽略用户设置的码率,由编码器自己控制码率,并尽可能保证画面清晰度和码率的均衡。
BITRATE_MODE_CBR
无论视频的画面内容如果,尽可能遵守用户设置的码率
BITRATE_MODE_VBR
尽可能遵守用户设置的码率,但是会根据帧画面之间运动矢量(通俗理解就是帧与帧之间的画面变化程度)来动态调整码率,如果运动矢量较大,则在该时间段将码率调高,如果画面变换很小,则码率降低。

KEY_COLOR_FORMAT

是因为Android的Camera预览,只支持NV21(默认)和YV12,但是MediaCodec却只支持编码成NV12和YU12,源数据却是NV21,那我们就需要先将数据转成对应的YUV再丢给编码器去编码。

ImageFormat.中可以查到

 * @see android.hardware.Camera.Parameters#setPreviewCallback
 * @see android.hardware.Camera.Parameters#setPreviewFormat
 * @see android.hardware.Camera.Parameters#getSupportedPreviewFormats
 * </p>
 */
public static final int YV12 = 0x32315659;

 * @see android.hardware.Camera.Parameters#setPreviewCallback
 * @see android.hardware.Camera.Parameters#setPreviewFormat
 * @see android.hardware.Camera.Parameters#getSupportedPreviewFormats
 * </p>
 */
public static final int YV12 = 0x32315659;

所以一定要保证输入的yuv格式需要跟配置的colorFormat对的上,如果对不上就需要转换成对应的YUV格式。
COLOR_FormatYUV420Planar = I420 = YV21 = 19,而COLOR_FormatYUV420SemiPlanar = NV12 = 21。

官方推荐去使用COLOR_FormatYUV420Flexible, YUV420Flexible并不是一种确定的YUV420格式,而是包含COLOR_FormatYUV411Planar, COLOR_FormatYUV411PackedPlanar, COLOR_FormatYUV420Planar, COLOR_FormatYUV420PackedPlanar, COLOR_FormatYUV420SemiPlanar和COLOR_FormatYUV420PackedSemiPlanar。

     /**
     * Flexible 12 bits per pixel, subsampled YUV color format with 8-bit chroma and luma
     * components.
     * <p>
     * Chroma planes are subsampled by 2 both horizontally and vertically.
     * Use this format with {@link Image}.
     * This format corresponds to {@link android.graphics.ImageFormat#YUV_420_888},
     * and can represent the {@link #COLOR_FormatYUV411Planar},
     * {@link #COLOR_FormatYUV411PackedPlanar}, {@link #COLOR_FormatYUV420Planar},
     * {@link #COLOR_FormatYUV420PackedPlanar}, {@link #COLOR_FormatYUV420SemiPlanar}
     * and {@link #COLOR_FormatYUV420PackedSemiPlanar} formats.
     *
     * @see Image#getFormat
     */
    public static final int COLOR_FormatYUV420Flexible            = 0x7F420888;

COLOR_FormatYUV420Flexible 它大体意思是,这是个通用包容的适配钥匙。

0X02 错误处理

01黑白画面

不同设备 COLOR_Format不同,可以尝试更换COLOR_FormatYUV420Flexible为其他具体的某一项(多见于MTK)。

02 level、profile设置不兼容

最安全的情况是将Profile设置为Baseline。

  mFormat.setInteger(MediaFormat.KEY_PROFILE, MediaCodecInfo.CodecProfileLevel.AVCProfileHigh);
  mFormat.setInteger(MediaFormat.KEY_LEVEL, MediaCodecInfo.CodecProfileLevel.AVCLevel31);

由于视频编码后显示的数据质量偏低,所以需要调整质量。这个时候需要在这个设置level、profile

Profile是对视频压缩特性的描述(CABAC呀、颜色采样数等等)。
Level是对视频本身特性的描述(码率、分辨率、fps)。
简单来说,Profile越高,就说明采用了越高级的压缩特性。
Level越高,视频的码率、分辨率、fps越高

在android7.0以下,android 内部写死了参数,编码出来的只能是Baseline,除非系统改过这个BUG,否者设置无效,甚至会导致configure参数失败。

0x03 呼吸效应定位处理

(1)现象:
呼吸效应在静止的场景下比较容易观察出来,运动场景中,大部分的图像内容都在变化,不容易发现。
表现为整个视频流,就会周期性出现清楚到模糊的突变。
(2)原因分析:
编码产生:
由于I帧的插入造成图像质量忽然变好,切换到P帧后又忽然变差。一般情况下,我们都会将I帧调的比较大,一个GOP内,离I帧越远的P帧,编码误差越大,图像降质也越严重,当下一个I帧出现时,图像又立即变得清楚起来。
产生的主要原因:I帧和P帧的编码模式和编码质量的不同,导致视觉上图像不连续。
物理镜头原因:
焦距就会发生变化,长对焦行程的定焦镜头或者变焦镜头容易出现这个问题
(3)解决方案:
编码产生:
重新调节 gop组大小和码率 帧率,保证I帧和P帧大小不要相差太大(保证编码质量稳定)。
镜头原因(不过多讨论)
1、调整焦距,2、采用像方远心设计。

0X04拖尾效应 处理

(1)现象:
动态画面似乎不连贯,运动不够流畅,运动影像后面总有一部分拖尾的现象。
(2)原因分析:
拍摄快速运动的对象时,画面帧率不足造成的。
(3)解决方案:
增加帧率和码率。

0X05 其他处理
生成视频增加位置坐标属性,mediaMuxer有提供api 实现。

  if (mediaMuxer != null) {
        mediaMuxer.setLocation(latitude, longitude);
    }
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 156,907评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,546评论 1 289
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 106,705评论 0 238
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,624评论 0 203
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 51,940评论 3 285
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,371评论 1 210
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,672评论 2 310
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,396评论 0 195
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,069评论 1 238
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,350评论 2 242
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,876评论 1 256
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,243评论 2 251
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,847评论 3 231
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,004评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,755评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,378评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,266评论 2 259

推荐阅读更多精彩内容