Android codec2 视频框架 之应用

文章目录

      • 应用流程
        • 外部主动获取输入和输出buffer
        • 外部设置回调
      • 内部流程

应用流程

在这里插入图片描述

外部主动获取输入和输出buffer

解码的调用流程,以android原生的一个bin来说明
android 原生代码位置: frameworks/av/cmds/stagefright/codec.cpp
frameworks/av/cmds/stagefright/SimplePlayer.cpp

编译出来的是codec的bin,使用bin播放mp4, 可以使用如下的命令进行调试。

screenrecord /sdcard/test.mp4
codec -pSR /sdcard/test.mp4
  • prepare: 跟编码同样的流程

    createByType: 根据MIME创建解码器。

    configure:配置视频宽高、fromat信息到解码器。

    start:启动解码器进行解码。
    获取输入和输出的buffer 队列:先dequeue有效的输入buffer,然后将extract到的csd数据放入到这块buffer 中, 将这块buffer在queue到codec中(作用是 将解码所需要的额外的数据 给到解码器,类似于ffmpeg中的extradata)。

  • start: dequeue所有可用的input 和output buffer。然后解析封装读取数据 将数据拷贝到dequeue出来的input buffer 中, 拷贝完成后 queue到解码器, 同时从解码器中尽可能多的取输出的buffer, 对每个输出buffer 获取显示的时间戳。跟现有的时间比较,到显示时间的范围内则调用renderOutputBufferAndRelease将buffer 显示出去。

        state->mCodec = MediaCodec::CreateByType(
                looper, mime.c_str(), false /* encoder */);
        CHECK(state->mCodec != NULL);
        err = state->mCodec->configure(
                format, isVideo ? surface : NULL,
                NULL /* crypto */,
                0 /* flags */);

        CHECK_EQ((status_t)OK, codec->start());
        CHECK_EQ((status_t)OK, codec->getInputBuffers(&state->mInBuffers));
        CHECK_EQ((status_t)OK, codec->getOutputBuffers(&state->mOutBuffers))

         err = state->mCodec->queueInputBuffer(
                            index,
                            0 /* offset */,
                            buffer->size(),
                            timeUs,
                            bufferFlags);


外部设置回调

大部分应用都不会主动去获取解码输入和输出buffer。 类似NuPlayer是通过外部设置回调。MediaCodec内部有输出或者输入buffer的时候 回调到应用层。

NuPlayerDecoder.cpp
void NuPlayer::Decoder::onConfigure(const sp<AMessage> &format) {
    sp<AMessage> reply = new AMessage(kWhatCodecNotify, this);
    mCodec->setCallback(reply);
}
void NuPlayer::Decoder::onMessageReceived(const sp<AMessage> &msg) {
    switch (msg->what()) {
        case kWhatCodecNotify:
        {
            switch (cbID) {
                case MediaCodec::CB_INPUT_AVAILABLE:
                {
                    int32_t index;
                    CHECK(msg->findInt32("index", &index));
                    handleAnInputBuffer(index);
                    break;
                }

                case MediaCodec::CB_OUTPUT_AVAILABLE:
                {
                    CHECK(msg->findInt32("index", &index));
                    CHECK(msg->findSize("offset", &offset));
   
                    handleAnOutputBuffer(index, offset, size, timeUs, flags);
                    break;
                }
}

内部流程

  • create 和configure

create:mediacodeclist中遍历所有的解码器 然后将所有match的解码器返回。 这个里面放的是component名字如c2.android.vorbis.decoder等等。 找到之后 就用这个名字来init mediacodec。

configure: 将format 和 surface 配置到解码器当中,。

  • format的configure

其中format可以存储很多信息 比如基本的图像宽高,解码器的类型等等。
configure将编解码的一些关键信息配置到编解码器 比如宽高、MIME、bitrate、frameRate 等等。

  • surface 的configure surface
  1. 在设置surface的流程中操作为nativeWindowConnect、设置一个surface的generaration,然后又重新connect、disconnect。
  2. 调用codec的setSurface, codec直接调用的channel 的setSurface。
  3. channel的setSurface不会调用mComponent->setOutputSurface, 因为初始化的时候对应的outputPoolId为0.
  • mediacodec 的start()
  1. 调用component 的start, 调用对应的SimpleC2Component的start(), 对应的每个解码器实现的onInit(),。
  2. mChannel->start, 调用channel的start
    这里有一个问题,如何决定要申请的buffer 是graphic 还是liner类型的。
    这在simpleC2interface中已经定义,会按照音视频的类型进行决定,视频 grahic,音频liner
    addParameter(
            DefineParam(mInputFormat, C2_PARAMKEY_INPUT_STREAM_BUFFER_TYPE)
            .withConstValue(new C2StreamBufferTypeSetting::input(
                    0u, isEncoder ? rawBufferType : codedBufferType))
            .build());

2.1 在Channel的start 中会根据是编码输入的surface 还是解码输出的surface 配置申请buffer的个数, 以及调用Component->createBlockPool,创建graphic的pool。会返回pool的allocatorID 和outputPoolId
对应于在底层的实现是在C2AllocatedGraphic。 同时为生成的pools->outputPoolId生成poolIdsTuning并将这个Tuning 设置到componet中。

2.2 调用mComponent->setOutputSurface: 设置surface到解码模块,使得后续可以从对应的nativewindow中申请buffer。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/124243.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

变压器试验VR虚拟仿真操作培训提升受训者技能水平

VR电气设备安装模拟仿真实训系统是一种利用虚拟现实技术来模拟电气设备安装过程的培训系统。它能够为学员提供一个真实、安全、高效的学习环境&#xff0c;帮助他们更好地掌握电气设备的安装技能。 华锐视点采用VR虚拟现实技术、MR混合现实技术、虚拟仿真技术、三维建模技术、人…

网络安全之CSRF漏洞原理和实战,以及CSRF漏洞防护方法

一、引言 总体来说CSRF属于一种欺骗行为&#xff0c;是一种针对网站的恶意利用&#xff0c;尽管听起来像跨站脚本&#xff08;XSS&#xff09;&#xff0c;但是与XSS非常不同&#xff0c;并且攻击方式几乎向佐。XSS利用站点内的信任用户&#xff0c;而CSRF则通过伪装来自受信任…

【MySQL数据库】 六

本文主要介绍了数据库原理中数据库索引和事务相关概念. 一.索引 在查询表的时候,最基本的方式就是遍历表,一条一条筛选 . 因此,就可以给这个表建立索引,来提高查找的速度 比如,按照id建立索引 在数据库上额外搞一个空间维护一些id 相关的信息, id:1 表的某个位置 id:2 …

Java TCP服务端多线程接收RFID网络读卡器上传数据

本示例使用设备介绍&#xff1a;WIFI/TCP/UDP/HTTP协议RFID液显网络读卡器可二次开发语音播报POE-淘宝网 (taobao.com) import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.ServerSocket; import java.net.Socket; impor…

2023年香港专才计划(输入内地人才计划)拿身份最新申请攻略!

2023年香港专才计划&#xff08;输入内地人才计划&#xff09;拿身份最新申请攻略&#xff01; 近年来&#xff0c;香港受持续的人口老龄化等多因素影响&#xff0c;2022年香港人口总计减少了约12.17万人&#xff0c;跌幅1.6%&#xff0c;其中净移出人数约9.5万人。在此背景下&…

通过创建自定义标签来扩展HTML

使用HTML时&#xff0c;例如&#xff0c;使用<b>标记显示粗体文本。 如果需要列表&#xff0c;则对每个列表项使用<ul>标记及其子标记<li> 。 标签由浏览器解释&#xff0c;并与CSS一起确定网页内容的显示方式以及部分内容的行为。 有时&#xff0c;仅使用一…

Leo赠书活动-06期 【强化学习:原理与Python实战】文末送书

✅作者简介&#xff1a;大家好&#xff0c;我是Leo&#xff0c;热爱Java后端开发者&#xff0c;一个想要与大家共同进步的男人&#x1f609;&#x1f609; &#x1f34e;个人主页&#xff1a;Leo的博客 &#x1f49e;当前专栏&#xff1a; 赠书活动专栏 ✨特色专栏&#xff1a;…

频次最高的38道selenium面试题及答案

1、selenium的原理是什么&#xff1f; selenium的原理涉及到3个部分&#xff0c;分别是&#xff1a; 浏览器driver&#xff1a;一般我们都会下载driverclient&#xff1a;也就是我们写的代码 client其实并不知道浏览器是怎么工作的&#xff0c;但是driver知道&#xff0c;在…

Mysql数据库 8.SQL语言 外键约束

一、外键约束 外键约束——将一个列添加外键约束与另一张表的主键&#xff08;唯一列&#xff09;进行关联之后&#xff0c;这个外键约束的列添加的数据必须要在关联的主键字段中存在 案例 创建原则&#xff1a;先创建不含外键的表也就是班级表 添加外键的方式 一般使用第一…

c语言练习10周(11~15)

将b串中的所有字母字符连接在a串之后并输出&#xff0c;a,b串最多30个字符。 题干将b串中的所有字母字符连接在a串之后并输出&#xff0c;a,b串最多30个字符。输入样例abcdef 1A2D3C4F5GG输出样例abcdefADCFGG #include<stdio.h> int main() {char a[30], b[30];int i0…

Java类和对象(1)

&#x1f435;本篇文章将会开始对类和对象的第一部分讲解 一、简单描述类和对象 对象可以理解为一个实体&#xff0c;在现实生活中&#xff0c;比如在创建一个建筑之前&#xff0c;要先有一个蓝图&#xff0c;这个蓝图用来描述这个建筑的各种属性&#xff1b;此时蓝图就是类&a…

如何手动获取spring/springboot中的IOC容器(全局上下文对象)?

IDE&#xff1a;IntelliJ IDEA 2022.2.3 x64 操作系统&#xff1a;win10 x64 位 家庭版 JDK: 1.8 文章目录 前言一、如何手动获取spring容器[ApplicationContext]&#xff1f;方式①&#xff1a;在启动类中获取spring容器方式②&#xff1a;自定义工具类实现ServletContextList…

临界资源,临界区,通信的干扰问题(互斥),信号量(本质,上下文切换问题,原子性,自身的安全性,操作)

目录 引入 概念 临界资源 临界区 干扰存在原因 互斥 信号量 引入 举例 概念 介绍 表示可用资源数 表示等待进程数 申请信号量 信号量的本质 全局变量? 共享内存? 不安全问题 -- 上下文切换 原子性 信号量自身的安全性 原子操作的意义 操作 引入 通信…

Cesium 相机设置

1.setView 直接跳转到目的地 // 设置相机位置 const position Cesium.Cartesian3.fromDegrees(113, 31, 20000); // setView通过定义相机目的地&#xff08;方向&#xff09;,直接跳转到目的地 viewer.camera.setView({ destination: position, // 位置设置 orientation: { //…

适合汽车音频系统的ADAU1977WBCPZ、ADAU1978WBCPZ、ADAU1979WBCPZ四通道 ADC,24-bit,音频

一、ADAU1977WBCPZ 集成诊断功能的四通道ADC&#xff0c;音频 24 b 192k IC&#xff0c;SPI 40LFCSP ADAU1977集成4个高性能模数转换器(ADC)&#xff0c;其直接耦合输入具有10 V rms性能。该ADC采用多位Σ-Δ架构&#xff0c;其连续时间前端能够实现低EMI性能。它可以直接连接…

专业135总分400+西安交通大学信息与通信工程学院909/815考研经验分享

今年初试发挥不错&#xff0c;400&#xff0c;专业课135&#xff0c;将近一年复习一路走来&#xff0c;感慨很多&#xff0c;希望以下经历可以给后来的同学提供一些参考。 初试备考经验 公共课&#xff1a;三门公共课&#xff0c;政治&#xff0c;英语&#xff0c;数学。在备考…

GaN HEMT 电容的分析建模,包括寄生元件

标题&#xff1a;Analytical Modeling of Capacitances for GaN HEMTs, Including Parasitic Components 来源&#xff1a;IEEE TRANSACTIONS ON ELECTRON DEVICES&#xff08;14年&#xff09; 摘要&#xff1a;本文提出了一种基于表面势的终端电荷和电容模型&#xff0c;包…

直接插入排序与希尔排序

&#x1f389;个人名片&#xff1a; &#x1f43c;作者简介&#xff1a;一名乐于分享在学习道路上收获的大二在校生 &#x1f43b;‍❄个人主页&#x1f389;&#xff1a;GOTXX&#x1f43c;个人WeChat&#xff1a;ILXOXVJE &#x1f43c;本文由GOTXX原创&#xff0c;首发CSDN&…

4.移位计算,乘除法运算

目录 一. 移位计算 &#xff08;1&#xff09;算数移位 &#xff08;2&#xff09;逻辑移位 &#xff08;3&#xff09;循环移位 二. 乘法运算 &#xff08;1&#xff09;原码的乘法运算 &#xff08;2&#xff09;补码的乘法运算 三. 除法运算 &#xff08;1&#xf…