MediaExtractor 是什么?

MediaExtractor 就是解复用器,将audio和video分离

Android 4.1目前支持mp4 mkv ogg wav flac amr ts mp3 ps aac wvm这几种分离器

其实android支持分离器支持的不好,很多格式都没有或者不够健壮,毕竟它一般是用在手机上,简单一些就够了,不过可以看到android media正在慢慢改进。

MediaExtractor 在哪被创建呢?

AwesomePlayer::finishSetDataSource_l() {

//如果是http网络流,会创建http datasource

mConnectingDataSource = HTTPBase::Create(
                (mFlags & INCOGNITO)
                    ? HTTPBase::kFlagIncognito
                    : 0);

//如果是本地流:

dataSource = DataSource::CreateFromURI(mUri.string(), &mUriHeaders);

//最终会调用        source = new FileSource(uri);

extractor = MediaExtractor::Create(
                dataSource, sniffedMIME.empty() ? NULL : sniffedMIME.c_str());

}

sp<MediaExtractor> MediaExtractor::Create(
        const sp<DataSource> &source, const char *mime) {

//sniff是很重要的模块,其目的是到底选择哪个MediaExtrator进行创建

//通过得到的mime创建对应的

if (!source->sniff(&tmp, &confidence, &meta)) {
            ALOGV("FAILED to autodetect media content.");

//例如:

} else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG)) {
        ret = new MP3Extractor(source, meta);
    }

}

//sniff是什么?怎么被使用的

Sniff就是用于判别到底使用哪个Extractor,调用每个MediaExtrator的sniff,得到一个分数,最后返回MIME

void DataSource::RegisterDefaultSniffers() {

//这里就是把每个Extractor的sniff function注册进去

RegisterSniffer(SniffMPEG4);
    RegisterSniffer(SniffMatroska);
    RegisterSniffer(SniffOgg);
    RegisterSniffer(SniffWAV);
    RegisterSniffer(SniffFLAC);
    RegisterSniffer(SniffAMR);
    RegisterSniffer(SniffMPEG2TS);
    RegisterSniffer(SniffMP3);
    RegisterSniffer(SniffAAC);
 //   RegisterSniffer(SniffMPEG2PS);
    RegisterSniffer(SniffWVM);

}

void DataSource::RegisterSniffer(SnifferFunc func, bool isExtendedExtractor) {

//很简单,把func放进list中     static List<SnifferFunc> gSniffers;

gSniffers.push_back(func);

}

bool DataSource::sniff(
        String8 *mimeType, float *confidence, sp<AMessage> *meta) {

for (List<SnifferFunc>::iterator it = gSniffers.begin();
         it != gSniffers.end(); ++it) {

if ((*it)(this, &newMimeType, &newConfidence, &newMeta)) {

//得到一个更大的sniff值

if (newConfidence > *confidence) {

//当获得的值  >= 0.6f时,表示就用这个extractor了,直接返回

if(*confidence >= 0.6f) {

break;

}

如何创建一个MediaExtractor?

目前android支持的extractor还是比较弱,可能需要自己新加入一些extractor,实现步骤

首先需要实现sniff,以mpeg4extractor为例:

// The sniffer can optionally fill in "meta" with an AMessage containing
    // a dictionary of values that helps the corresponding extractor initialize
    // its state without duplicating effort already exerted by the sniffer.
    typedef bool (*SnifferFunc)(
            const sp<DataSource> &source, String8 *mimeType,
            float *confidence, sp<AMessage> *meta);

bool SniffMPEG4(
        const sp<DataSource> &source, String8 *mimeType, float *confidence,
        sp<AMessage> *);

需要实现检测功能,例如读取一部分数据,解析后检测是否为该格式。根据检测结果返回分数。

在DataSource.cpp中

void DataSource::RegisterDefaultSniffers() {

RegisterSniffer(你的extractor)

}

sniff完成后,就需要实现具体的extractor了,open的function:

class MediaExtractor : public RefBase {
public:
    static sp<MediaExtractor> Create(
            const sp<DataSource> &source, const char *mime = NULL);

virtual size_t countTracks() = 0;
    virtual sp<MediaSource> getTrack(size_t index) = 0;

enum GetTrackMetaDataFlags {
        kIncludeExtensiveMetaData = 1
    };
    virtual sp<MetaData> getTrackMetaData(
            size_t index, uint32_t flags = 0) = 0;

// Return container specific meta-data. The default implementation
    // returns an empty metadata object.
    virtual sp<MetaData> getMetaData();

enum Flags {
        CAN_SEEK_BACKWARD  = 1,  // the "seek 10secs back button"
        CAN_SEEK_FORWARD   = 2,  // the "seek 10secs forward button"
        CAN_PAUSE          = 4,
        CAN_SEEK           = 8,  // the "seek bar"
        CAN_SEEK_TO_ZERO   = 16, // the "previous button" for ADIF clips
    };

// If subclasses do _not_ override this, the default is
    // CAN_SEEK_BACKWARD | CAN_SEEK_FORWARD | CAN_SEEK | CAN_PAUSE
    virtual uint32_t flags() const;

// for DRM
    void setDrmFlag(bool flag) {
        mIsDrm = flag;
    };
    bool getDrmFlag() {
        return mIsDrm;
    }
    virtual char* getDrmTrackInfo(size_t trackID, int *len) {
        return NULL;
    }

stagefright 架构分析(四) MediaExtractor相关推荐

  1. 史上最全金融产品架构分析四:信托公司

    1.业务种类 ​ 信托业可以经营的业务项目依<信托投资公司管理办法>法可分为如下: (1)受托经营资金信托业务.即委托人将自己合法拥有的资金,委托信托投资公司按照约定的条件和目的,进行管理 ...

  2. stagefright 架构分析(六) 创建一个 Soft Decoder

    参考代码 在android中,已经有一些soft decoder,例如AAC AMR AVC等,这些都是软解的decoder,如果想自己加入一种decoder,可以参照这些代码的写法. 例如frame ...

  3. Android display架构分析-SW架构分析(1-8)

    参考: Android display架构分析二-SW架构分析 Android display架构分析三-Kernel Space Display架构介绍 Android display架构分析四-m ...

  4. pass基础架构分析

    pass基础架构分析 Relay 和 TVM IR,包含一系列优化passes,可提高模型的性能指标,如平均推理,内存占用,或特定设备的功耗.有一套标准优化,及特定机器学习的优化,包括常量折叠,死代码 ...

  5. Android10.0 日志系统分析(二)-logd、logcat架构分析及日志系统初始化-[Android取经之路]

    摘要:本节主要来讲解Android10.0 日志系统的架构分析,以及logd.logcat的初始化操作 阅读本文大约需要花费15分钟. 文章首发微信公众号:IngresGe 专注于Android系统级 ...

  6. 研究项目: JBoss架构分析

    原文转自:http://www.huihoo.org/jboss/jboss.cn.html 研究项目: JBoss架构分析 Jenny Liu School of Information Techn ...

  7. Deep Learning论文笔记之(六)Multi-Stage多级架构分析

    Deep Learning论文笔记之(六)Multi-Stage多级架构分析 zouxy09@qq.com http://blog.csdn.net/zouxy09          自己平时看了一些 ...

  8. Log4j2架构分析与实战

    为什么80%的码农都做不了架构师?>>>    1 系列目录 2种日志接口框架,4种日志实现框架 jdk-logging.log4j.logback日志介绍及原理 jcl与jul.l ...

  9. IOT(30)---庆科物联网平台架构分析

    庆科物联网平台架构分析 之前在介绍国内物联网平台的发展时曾经说到,物联网有两个发展路径,一是云端服务商选择和设备厂商合作推出完整解决方案,如阿里物联.微信硬件等等:二是模组设备厂商选择和云厂商合作并后 ...

最新文章

  1. 3D目标检测深度学习方法之voxel-represetnation内容综述(二)
  2. 海量数据处理利器之Hash——在线邮件地址过滤
  3. Java源码分析--Enum
  4. POJ - 2826 An Easy Problem?!(计算几何,好题)
  5. 【原】Linux设备网络硬件管理
  6. vue打包后获取不到数据_vue 打包后,如何修改接口地址?
  7. 使用7zip把jre集成到绿色运行程序内
  8. sql azure 语法_如何:Azure中SQL Server文件快照备份
  9. 学习spring第一天
  10. 目标管理体系:OKR
  11. 第三章 Guarded Suspension模式 等我准备好哦
  12. 程序员:迟到1分钟罚300,加班却视而不见,月底工资让人寒心
  13. kafka sparksteaming
  14. c语言1 qnan,什么是 1.#QNAN?
  15. 多人同时编辑excel,只需一招就搞定
  16. 英语中的 姓氏/Surname
  17. linux程序间管道通信,linux进程间通信——管道 详解
  18. 分享一个超大文件编辑器(WINDOWS 文本编辑器)
  19. unity制作坦克大战
  20. 本地服务器模板网站怎么安装,使用dedecms搭建自己的本地网站(全程图解)

热门文章

  1. Qt利用JavaScript访问网页元素(百度博客下载例子)
  2. aspx网页_微软网页设计工具Expression Web快速入门
  3. 英语不好能学会python吗_英语不好可以学习python编程吗?老男孩python入门
  4. 关于vmware p2v 转换后无法启动情况相关处理流程(仅作参考)
  5. ABAP AMDP数据库存储过程(数据源)
  6. Oracle切换到scott用户
  7. 第八章 USB 设备驱动移植
  8. 网络安全与网站安全及计算机安全:如何使用Kali Linux进行Windows计算机操作系统安全演练
  9. 仿QQ弹出窗口 gggggggggggg
  10. C++可微编程:寻找一种最佳的图像抖动模式