framework MediaCodec解码流程分析

来源:互联网 发布:刚柔流空手道 知乎 编辑:程序博客网 时间:2024/06/05 00:51

MediaCodec到底是硬解码还是软解码?

MediaCodec 调用的是在系统中register的解码器,硬件厂商会把自己的硬解码器register进来,就是硬解,如果他register一个软解码器,则是软解。

MediaCodec并不是真正的codec,真正codec是在openMax,要保证是硬解,在MediaCodec里有接口可以枚举所有解码器,每种编码可能都有多个解码器,

区分哪个是软解哪个是硬解就行。

在framework中创建MediaCodec 解码器对象。   

    mLooper = new ALooper;
    mLooper->setName("my_avc_decoder_looper");
    mLooper->start();

   // 参数一,传入一个循环线程,参数二,创建的解码器类型,参数三,false 创建解码器。

   mCodec = MediaCodec::CreateByType(mLooper, "video/avc", false);

可以看到我选的”video/avc” - H.264/AVC video是一种H264的解码方式,但并不能证明我使用的就一定是硬解码

我们先来看一下Android系统中解码器的命名,软解码器通常是以OMX.google开头的。硬解码器通常是以OMX.[hardware_vendor]开头的,比如TI的解码器是以

OMX.TI开头的。当然还有一些不遵守这个命名规范的,不以OMX.开头的,那也会被认为是软解码器。

判断规则见frameworks/av/media/libstagefright/OMXCodec.cpp:

static bool IsSoftwareCodec(const char *componentName) {
    if(!strncmp("OMX.google.", componentName,11)) {
        returntrue;
    }
    if(!strncmp("OMX.", componentName,4)) {
        returnfalse;
    }
    returntrue;
}

其实MediaCodec调用的是在系统中注册的解码器,系统中存在的解码器可以很多,但能够被应用使用的解码器是根据配置来的,即/system/etc/media_codecc.xml。

这个文件一般由硬件或者系统的生产厂家在build整个系统的时候提供,一般是保存在代码的device/[company]/[codename]目录下的,例如device/samsung/tuna/media_codecs.xml。这个文件配置了系统中有哪些可用的codec以及,这些codec对应的媒体文件类型。在这个文件里面,系统里面提供的软硬codec都需要被列出来。

也就是说,如果系统里面实际上包含了某个codec,但是并没有被配置在这个文件里,那么应用程序也无法使用到。

在这个配置文件里面,如果出现多个codec对应同样类型的媒体格式的时候,这些codec都会被保留起来。当系统使用的时候,将会选择第一个匹配的codec。除非是

指明了要软解码还是硬解码,但是Android的framework层为上层提供服务的AwesomePlayer中在处理音频和视频的时候,对到底是选择软解还是硬解的参数没有设置。

所以虽然底层是支持选择的,但是对于上层使用MediaPlayer的Java程序来说,还是只能接受默认的codec选取规则。

但是Android提供的命令行程序/system/bin/stagefright在播放音频文件的时候,倒是可以根据参数来选择到底使用软解码还是硬解码,但是该工具只支持播放音频,不

支持播放视频。

一般来说,如果系统里面有对应的媒体硬件解码器的话,系统开发人员应该是会配置在media_codecs.xml中,所以大多数情况下,如果有硬件解码器,那么我们总是

会使用到硬件解码器。极少数情况下,硬件解码器存在,但不配置,我猜只可能是这个硬解码器还有bug,暂时还不适合发布,所以不用使用。


下面主要分析的是MediaCodec的解码流程?

    mLooper = new ALooper;
    mLooper->setName("my_avc_decoder_looper");
    mLooper->start();

    // 参数一,传入一个循环线程,参数二,创建的解码器类型,参数三,false 创建解码器。

    mCodec = MediaCodec::CreateByType(mLooper, "video/avc", false);


特别说明:Alooper 对象是android 异步消息框架的无线循环体。在android 应用层开发中应该会经常用到异步消息框架(Looper、Handler、Message),

在framework层也是同样的异步消息框架,对应的是ALooper、AMessage、AHandler主要用于异步消息处理,在ALooper中会无线循环判断

 do {
 } while (loop());

在loop()中判断消息队列EventQueue如果没有消息就一直阻塞等待。如果有消息则进行消息分发。


    sp<AMessage> format = new AMessage;
    format->setInt32("width", mWidth);
    format->setInt32("height", mHeight);
    format->setString("mime", "video/avc");

       mCodec->configure(format, mSurface, NULL,0);   
       mCodec->start();  //启动MediaCodec ,等待传入数据



      //Vector<sp<ABuffer> > inbuffers;
      err = mCodec->getInputBuffers(&mInbuffers);  //用来存放目标文件的数据
    if (err != NO_ERROR) {
        ALOGD("Unable to get input buffers (err=%d)\n", err);
        mCodec->stop();
        mCodec->release();
        mCodec.clear();
        return err;
    }
    //Vector<sp<ABuffer> > outbuffers;
    err = mCodec->getOutputBuffers(&mOutbuffers); // 解码后的数据
    if (err != NO_ERROR) {
        ALOGD("Unable to get output buffers (err=%d)\n", err);
        mCodec->stop();
        mCodec->release();
        mCodec.clear();
        return err;
    }

// 准备工作完毕 开始传输人数据

mCodec->dequeueInputBuffer(&inbufIndex, kTimeout);

sp<ABuffer> inputBuffer = mInbuffers[inbufIndex];;//inbuffers[inbufIndex];

// input 输入数据

memcpy(inputBuffer->data(),input+in_offset,inCount);
mCodec->queueInputBuffer(inbufIndex, 0, inCount, timestamp, flags);


       size_t outbufIndex = 0 ;
        size_t offset, size;
        int64_t ptsUsec;
         uint32_t flags;
        mCodec->dequeueOutputBuffer(&outbufIndex, &offset, &size, &ptsUsec, &flags, 5000);//

     // 解码之后渲染到surface

      if(mSurface !=NULL)
                    mCodec->renderOutputBufferAndRelease(outbufIndex);





阅读全文
'); })();
0 0
原创粉丝点击
热门IT博客
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 做b超能检查出什么妇科病 妇科病图片 妇产科在线医生咨询 现代女子医院 广州女子医院 产科医生在线咨询问答 女人妇科病 鸭嘴钳 妇检前注意事项 b超可以检查出什么妇科病 常见妇科病有哪些症状 妇检有哪些项目 儿科在线医生有问必答 fuke 女子医院咨询 妇科病怎么检查 阴道镜检查需要多少钱 女人妇科病怎么引起的 妇科病的症状 怎样预防妇科病 妇科病有什么症状 咨询医生妇产科 妇产科免费咨询医生 b超能检查出什么妇科病 有问必答网 异常白带 妇科病有哪些 妇科病的常见症状 女性妇科病 妇科病症状自测 女性体检 女性炎症有哪些表现 北京妇产科排名 在线咨询医生妇产科 妇科病有哪些症状白带 盆腔检查 妇科病怎么办 妇科病是什么 北京协和医院妇科专家 上海哪家医院看妇科好 上海哪家医院看妇科比较好