每天一点点音视频相关_Android上的音视频编解码概述之硬编

Android 上支持硬件编解码, 所谓硬件编解码,就是专门的电子模块来处理编解码,它就是硬件视频流编解码器, VPU (Video processing unit)

Android中实现音视频编解码的过程, 牵扯到三个类: MediaCodec, MediaExtractor, MediaMuxer

回顾之前介绍的音视频编码的流程:

音视频文件 -> 解封装(Extractor) -> 解码(MediaCodec) -> 原始音视频数据

对应着:

音视频文件 -> MediaExtractor –packet–> MediaCodec –Frame–>

回顾之前介绍的音视频解码的流程:

原始音视频数据 -> 编码(MediaCodec) -> 封装(Muxer) -> 音视频文件

对应着:

–Frame–> MediaCodec –packet–> MediaMuxer -> 音视频文件

这里对比着写出来,很相似,我之前以为这就是规范,在其他平台上,也是这样称呼的,后来我知道了 ffmpeg, 发现还有其他说法。

明天: 每天一点点音视频相关_Android上的音视频编解码概述之软编

每天一点点音视频相关_音视频文件概述

我们知道, 文件是有格式的, 比如 mp3 格式, txt格式, 文件的格式一般是文件名的后缀, 比如 不可描述.mp4, Windows 系统还会根据这个后缀来决定它被什么打开,显示什么样的图标。但是实际上, 在其他系统上 比如 linux, unix上, 文件的格式更多的是通过文件头部的魔数来确定。

重点来了

音视频文件常见的格式有: mp3, mp4, avi 等等, 平时说的,是上面说的那层含义, 后缀是 .mp4, 或者魔数代表的格式, 这是封装格式, 容器格式。

容器里面装的是压缩了的音视频数据, 以 packet 为单位, 一个一个的。

压缩(编码)的格式是另一回事了, 比如 h263, h264

上节说道的

编码, 就是用 h264 编码器编码

封装, 就是用 mp4 封包器, 把编码的包, 装进 mp4 文件里

解码, 与之相反。


明天: 每天一点点音视频相关_Android上的音视频编解码概述

AtomicHabitss实践_每天一点点音视频相关

一个习惯的形成需要从以下四个方面动手:

  1. 信号,提示 (好习惯的信号要加强,提高出现的频次,坏习惯的信号要避开)
  2. 渴望 (当有了一个信号, 只有当我们有所渴望才会出现行动, 比如看到甜食信号,我们的本性喜欢甜食,向获取糖分能量,所以才会有行动, 渴望的增强与本能,社会认同有关)
  3. 行动 (行动要尽量的简单, 本文就是来做这个的)
  4. 反馈 (采取了行动后,有正反馈才会形成循环, 本文的这个行动,暂时还没有比较明显的反馈, 可能是写下一点,我的心会舒服一点,但是者好像不太好使)

针对以上四个方面:

  1. 每天九点吃完饭是一个信号, 吃完饭,九点多, 我会坐在电脑前, 开始写今天的知识点。
  2. 渴望, 我希望我要成为这个领域的专家,能够解决所有问题,这时候我就有更多的选择权主动权,也就是我就能够更自由
  3. 每天一点点, 完成今天的,创建好明天的文件,方便开始,每天,我坐在这,可以直接开始写知识点
  4. 反馈 (各种层次的反馈,还没相好,不过还是有几个的,比如标签云里音视频的标签会逐渐变大,文章数量会变多,可能还需要一些更直接的,比如每天完成吃个香蕉,听会歌,看个搞笑视频)

每天一点点,这个其实我之前实践过,那时候还在北京,那时看了《微习惯》的结果,我现在发现,微习惯就是这里所说的行动的部分。那时候使用一个《Loop》来打卡,可以说我的吉他入门就是这样养成的,但是后来我那些习惯又没了,为什么? 读 《Atomic Habits》会得到答案,因为环境改变了,环境属于信号阶段。在北京的时候,下半回家十点,回去就开始行动,下班回家就是个信号,但是后来离开北京,回家待了段时间,那个信号就没了。所以那时后特别想稳定下来,那时候虽然不知道这个道理,但是向稳定下来是对的。

那今天的知识点:

一个音视频文件的解码过程如下:

音视频文件 -> 解封装(Extractor) -> 解码(MediaCodec) -> 原始音视频数据

一个音视频文件的编码过程如下:

原始音视频数据 -> 编码(MediaCodec) -> 封装(Muxer) -> 音视频文件

明天:每天一点点音视频相关_音视频文件概述

学英语有感

最近在使用流利说和开口说英语来学习英语, 每天打卡。

发现了网上学英语的这种 App 的一个统一套路, 显示来个七天免费或者几块钱体验, 这说明了对自己产品的信心吧。体验开始,分到某个班里,然后有专门的老师来崔打卡,这个老师还有个专有名词, “班班”, 对,不同的软件的,都叫班班,看来形成了行业职业了。班级是以微信群组织的, 流利说要更高级一些,班级会在软件里显示,每天有学习的排名。

流利说,对数据这块做的很充分,每天的学习市场,打卡天数,学习效率(包括其他一些详细信息),平均分(课程得分的平均),成长什么的,很详细。关键, 它有的产品时会根据指标反学费的,我就因此报了个半年的,哈哈哈。跟我妈说,她说反不反还不是它说了算。这倒也是,惊讶与我妈会有如此高见的同时,心想我会不知道,所以我每天都在研究各项分数的关联。不过呢,人家班班也给我一些达标的攻略,当时,我还是很震惊的。不过现在想来,人家给攻略的心态可能是这样的, “凭我对大多数人的研究, 我就算告诉你应该怎么做,这是需要坚持的,你还是做不到”,实际上也的却是这样子,长期坚持一件事,即使很简单也不一定能做到,况且真的不容易。

我体验了一个月后,明显发现自己的听力提高了,能听懂的很多了,不过课程还是很多不能达标,我现在是三级,三级最后有个测验,需要把所有课程都达标三颗星才能开启,太难了,主要说上,不过我还是能感觉到自己的进步。然后,这种机制让我不得不去刷每一个课程,反正当年我学习没有这么把一个课文这么熟悉过。

总结下来,流利说,有这么几个套路:

  1. 借助通讯软件形成小圈子,有班级,有小组,有班班,(原子习惯里说的环境,影响的是渴望这个阶段,不想落下,圈子的共识,学好英语)
  2. 智能评分, 对说的评分很智能(语调, 流利度, 发音的准确性,重读什么的,也不知到怎么做到的,反正很夫妻, 这是原子习惯里说的习惯形成的反馈奖励阶段)
  3. 数据这块之前说过了(这会影响原子习惯里反馈和渴望这个阶段)
  4. 分级,每一集分几个单元和最后的测试,每个单元分几个部分。每个部分包括几个课(主课文,单词课,对话课)和三个游戏。难度是递增的。每个课至少一颗星才能开锁下一颗。每个课至少两颗星才能开启下个单元,每个课至少三颗星才能开启本集的测试。测试还是挺难的,第二级的测试我都没过。话说这个初始的评级,是通过测试册出来的,我就直接跳过了一二级。不过呢,测试题是根课文联系的,所以对前面课文不熟悉,直接测试就难了。
  5. 每个课的学习是这样的,一句一句学习,每一句都可以重复听,并可以复读,复读会有评分反馈。

开口说英语的课程不是太熟悉,现在感觉到的几个套路:

  1. 同样借助软件形成圈子,打卡
  2. 全英文的教学,两个老外在那扯,讲解对话课程, 感觉有分为,但是有点被动,很长的扯完后,做题

其实,我想说的是流利说,很看好他,真的是将智能和人工搭配的很棒,加之,我最近在看原子习惯,也就总结出它在这方面所表现出的优势。


原子习惯(Atom Habits)

梦想破灭后

梦想破灭, 这好像是一个很高级的词, 电影里才出现, 我们平时才不会这么说。我这里这么说了, 我想记录下自己的那种感觉, 并不是抱怨吐槽,撒气,只是想记录一下。

我有一个梦想, 我想移民外国。这好像也没啥, B站看看,好多移民新西兰呀,其他国家的。但是对于我周围的人来说, 包括我自己, 这可是大梦想。但是我在为之努力。

之前攻略过, 出国的条件, 我还差一些, 主要时英语差, 所以,我一直有提高英语的想法, 最近开始花时间, 使用琉璃说练习, 在感觉到自己的英语差, 感觉到自己的英语有进步的同时, 我也在感慨用软件学习的优势, 细化到每个发音, 每个音调, 每个重音, 及时的反馈奖励,让我欲罢不能。

今天又去搜关于新西兰移民, 看到的都是说新西兰不好, 工作机会很少, 工资跟国内大城市比不怎么高, 房子也很贵, 也会加班, 等等吧。顿时,就感觉到前途黑暗,没有方向。当然,这太情绪化了,我现在虽然还是有一点茫然,但是也没啥, 跟失恋的感觉比,舒服多了。我只是想记录一下。不过,这也对我造成了梦想的改变, 我只前梦想着去新西兰,现在想着其他国家也可以。哈啊哈哈

其实呢,关于移民,我肯定不是简单因为外国的月亮是圆的所以移民。我其实想要一种超越,超越自己的限制,我希望能像那些随便想去那个国家就去那个国家生活的人。当然,这真的就是梦想,但是我觉得可以实现。而且,我觉得随着我们国家在国际地位的提升,就可以实现。在 2018 年,我在国内云游几个省,然后到成都生活工作了一年, 我希望有一天在全球达到这种状态。

刚才吃饭的时候,发呆,瞪着水泥地面,突然地面开始晃动,摇曳,像是在水底一样,感觉很神奇, 我立马警醒,去看了看煤气炉,这才放心。然后回来继续发呆,竟然还可以进入,摇曳,神奇,就像在海底游荡。我可能发烧了。

读《BDD in Action》(4)

第三部分才开始讲编程写代码, 我好兴奋呀!!

Chapter7 验收测试

好的验收测试需要遵循一下规则:

  1. 首先应该是沟通工具
  2. 提供有效的反馈
  3. 值得信赖, 如果成功了,表示系统是正确的
  4. 用以维护

自动化安装过程

一些策略:

  1. 在每个测试前都要初始化数据库
  2. 如果,再每个测试之前初始化数据太耗时,可以再每个测试集合之前初始化数据库
  3. 使用测试 Hook
  4. 再 Scenario 里使用特定的数据,而不是去读数据库
  5. 使用角色, 比如使用具体的某个人 John, 初始化他的信息,然后操作

分离 what 和 how

自动化验收测试应该是稳定的, 不经常变化的,所以需要分离实现。 通过分离抽象层的方法,可以解决。一般分三层:

  1. 业务规则层 一般就是 feature 里的 Scenario 的描述,注重的是 输出
  2. 业务流程层 一般就是 step 里的代码
  3. 技术层 代表了用户如何与系统交互

Chapter8 为 UI 层写验收测试

UI 测试是非常慢, 为了快一点, 可以使用模拟什么的,避免太多的 UI 测试, 因为 UI 是细节, 容易改变。

两种情况需要 UI 测试:

  1. 演示用户在系统内的移动
  2. 演示业务规则是如何表现在用户接口上的

UI 测试很好的展示了用户与系统的交互, 当不知道是否需要 UI 测试时,可以问问自己是否需要展示用户与系统的交互。

WebDriver 是一个可以使用代码来模拟用户与系统的操作的库, 实际是一个抽象层, 可以用代码来造作各种浏览器。具体的操作,这里不做描述。

Page Object 模式

Page Object 是一个网页或者它一部分的模型, 包含一系列针对业务的方法, 将实现细节与业务分开。它有两个主要的作用:

  1. 将技术实现与测试分开, 让测试代码更简单更容易维护
  2. 将与网页操作的代集中了,当网页有改动时,影响测试代码不会很多

Page Object 属于之前提到过的技术层, 它提供了对业务流程层友好的服务。

如何书写设计良好的 Page Object

  1. Page Object 应该只暴露简单类型和领域对象
  2. Page Object 应该暴露状态
  3. 也可以导航到其他页面

Chapter9 非 UI 验收测试

业务逻辑包括:

  • 用户的某个行为会导致什么业务输出
  • 你的应用或者业务与竟品有什么不同, 与要替换的旧的比有什么好的
  • 应用什么业务规则
  • 需要对用户做什么业务限制

非UI测试主要如下几种:

  • 针对与 controller 的测试
  • 直接针对业务逻辑的测试
  • 对远程服务的测试
    现在比较流行的 SOA, 面向服务的架构, 就是将单独的功能的服务单独提供出来, 一般使用 Restful 接口。

非功能性需求:

一般包括性能需求, 安全需求, 稳定性需求, 访问性需求等

Chapter10 BDD 和单元测试

TDD (Test-Driven Development) 测试驱动开发的两个基本原则:

  1. 先写一个失败的测试,指明功能代码要实现的功能
  2. 重构来去掉重复,提高代码质量

它的最大的好处在于在写代码之前,促使用户去思考要写的代码的目标

BDD 可以再所有不同的层次来用于说明行为, 既可以说明一个业务需求的行为, 也可以说明一个类的行为

BDD 是建立在 TDD 实践之上

一些实践:

  1. 从外向内的开发确保代码交付所需要的行为
  2. 使用共享的领域语言来实现统一的理解达成共识
  3. 用例来更清楚的描述行为
  4. 再高层级和更细节的层次都描述系统的行为

从外向内的开发的一般步骤:

  1. 从一个高层的验收测试开始
  2. 写 step 文件
  3. 实现 step, 考虑底层代码应该如何实现
  4. 根据 step 的实现,写单元测试来说明底层代码的行为
  5. 实现代码

在写某个单元测试,但是实现它需要另一个类或者方法时,通常有三种做法:

  1. 立刻实现这个类或者方法, 这适合比较简单的情况,可以把正在写的单元测试用 @Ignore 标记,从而保证总是只有一个单元测试需要完成
  2. 实现一个最小版本的类, 等会再回来, 这时候当前的测试实际是一个集成测试
  3. 使用一个假的(fake, stub, mock),直到当前测试完成,再回来

读《BDD in Action》(3)

Chapter 5 从 examples 到 可执行的 specifications

把具体的用例编程可执行的 scenario

有一些可以自动执行 Specifications 的软件如 JBehave, Cucumber 等等

下面是一个 Feature 文件:

一个 Feature 文件包含了一些 Scenario

Scenario 的标题简短凝练, 强调与其他 Scenario 的不同, 它们同在一个 Feature 里共享相同的上下文。

Scenario 使用特定的结构,使用特定的关键字

Given 后面的 context 设置了一个舞台, 描述了测试的前提条件, 安装好测试数据, 让应用进入正确的测试状态。有时候只是提供一个说明,没有实际操作。

必须注意的是, 之包含那些与该测试直接相关的先决条件,不然会造成难以理解。

When 后面的是一些要测试的行为事件, 它们会产生输出, 在 Then 里面检验

除了以上基本的关键字, 还有 and 和 but, 让结构更清晰

还可以使用 # 加注释, 也可能使用 !– 引导注释

使用表格消除重复

消除重复的一个很牛的方式就是使用查表法来复用一条流程

从这样的重复

到这样的查表法

Background 关键字 提供 Scenarios 功用的前提条件

Chapter 5 自动化执行 Scenarios

这一章牵扯到具体的实现的使用, 这里不做说明, 因为关于库的使用最好的地方是官方文档。这里只说一些原理性的东西。

一个 Scenario 里包括很多步, 它们会被转化成对应的方法。

这样做的原因是为了避免重复, 实现了文本到代码的转化。也保持了一致性, 一旦修改了某个 Scenario 的某一步, 导致了文本和代码的不一致, 这个 Scenario 就会变为 pending 状态。

读《BDD in Action》(2)

chapter 4

这一章要来学习如何通过 Feature 提供软件的功能, 会学习一些用来描述和讨论 Feature 的技术。

  1. feature 是帮助用户或其他利益相关者来实现业务目标的软件功能。feature 不是 user story, 但是可以被多个 user story 描述。

  2. user story 将 feature 分解成更可管理的部分,从而更容易实现,表达

  3. BDD 实践者通过 concrete example 来实现对一个 feature 达成共识。这些用例可以避免歧义和不确定性。

  4. 管理不确定性在 BDD 实践中举足轻重。有经验的实践者会尽量避免太早明确定义方案,会保持开放选项,直到了解的足够多了才会提交当前最合适的方案。这叫做 Real Options。

  5. Deliberate Discovery 通过管理不确定性和忽略来降低项目风险

  6. 这些用例作为 automated acceptance criteria, 指导开发者实现功能,从而驱动开发进程。

什么是 feature?

在敏捷项目中, 开发者用了很多词来描述他们想要构建的东西。比如 Epics, capabilities, themes, requirements, features, use cases, user stories。 尽管这些词出来好久了,但也没有明确定义,很多团队还会为此辩论。

我们真正想要的是能够描述我们认为的用户的需求。我们像以一种用户能够理解的方式表达我们自己, 以便于他们可以尽早检验我们的理解,提供帮助,提供反馈。

我们使用的词应该能简化我们对用户需求的讨论:

  1. 定期交付有形的,可见的业务价值
  2. 获取反馈,一边我们走在正确的方向上

这些不同的词,都是在不同的层次将上层需求分解到可管理的大小, 使用那些词依赖与你的项目的大小和复杂性。下面介绍词:

  • Capabilities 是提供给用户某种能力让他们能实现某种业务目标,或者执行某个有用的任务。不依赖特定的实现。比如“用户可以使用它添加滤镜”。

  • Features 是一种软件功能, 牵扯到实现了, 比如: 在拍摄的时候添加滤镜。

  • 当交付 Features, 你可以使用 user stories 分解它, 从而更好管理,更好计划和组织工作。

  • 可以使用 examples 来理解 Features 是如何帮助用户的, 引导 user stoies 的工作。

Features 交付 Capabilities

用户更我们要功能,我们最终交付给他的是实现了某种功能的软件。

Feature 可以被相对独立的交付,不依赖其他的 Feature,可以被用户单独测试。Feature 可以被用来对某一个发布要包含什么做计划,或者写文档。

Feature 使用业务术语, 如果写用户手册,就会有 Feature 的介绍。

下面来距离说明一下描述 Feature 的格式的重要性。

Feature: 线上会员续费
In order to 更容易的续费我的会员
As a 这个公司的会员
I want to 在线续费会员

简短的一个标题, 避免具体实现。在排期,设计,实现之前,都可以只使用这个标题。

在需要具体的时候,就可以使用上面的格式。
目标是为了提醒你为什么它是必要的,是为了实现某个 capability。帮助我们检查这个 Feature 是否真的有必要。可以问自己一下问题:

  1. 这个 feature 真的能实现这个业务目标?
  2. 如果不能,那它实现什么目标?
  3. 基于我现在所知,它是否还有必要?

下一步, 标出这个 Feature 会影响的用户, 以它的视角来检视这个 feature。

最后,描述具体做什么,这时候,还不需要与具体技术实现关联。

有时候,不是从用户的角度看这个 Feature, 而是从利益相关者,比如同样是上面的 Feature, 可以这样:

Feature: 线上会员续费
In order to 减少用户流失带来的销售额下降
As a 这个公司的销售主管
I want to 在线续费会员

这里很有趣, 换成从利益相关者的角度看着 Feature, 立马视野开阔了, 可能不必非得这个 Feature 还有其他更好的方式

另外, 还可以有其他的描述形式:

Feature: 线上会员续费
As a 这个公司的会员
I want to 在线续费会员
So that 更容易的续费我的会员

最后要说的时候, 没有什么标准的形式, 团队,项目里有统一的形式的好了。(开且不同的形式可能会有不同的关注点,用多种方式探究也不错吧–译者注)

Feature 可以分解成可以更容易管理的块

Feature 有时后可能还太大,可能一个迭代里都实现不,所以需要按功能分解成更小的块。这些块叫做 “user stories”。如下图,在分解的时候可能要经过多层分解:

分解 Feature 有两种策略。一种如上,把一个把一个业务流程分成小的具体一点的业务流程但是不牵扯实现。

另一种是分解成这个业务流程包括那些步,如下:

这是危险的,过早的把具体的步骤,可能不是最适合的方案。

Feature 可以分解成更多的 user stories

user stories 也会将实现细节推迟,等到掌握更多信息时再谈实现

Feature 不是 user story

  • Feature 是交付给用户或利益相关者的,为了提供某种能力来实现业务目标

  • User Story 是一个计划工具,帮助你为 feature 提供更多细节

Feature 可以在比较的时候写,但是 User Story 可以在邻近实现的时候写。

Epics 实际就是很大的 user story, 需要在分,本书不讨论

总有例外不是和这个层级结构

用 examples 实例化 features

Examples 是 BDD 的核心。在和用户或利益相关者交流时,开发者使用 examples 来加深对 Feature 的理解。扫除不确定性。

根据 David Kolb 的”基于实验的学习“理论, 有效的学习包含四个步骤:

书里通过一个例子,通过不断跟一个安全专家询问不同的密码是否安全,最后确定需求

感觉没讲清楚呀

Real Options:

这是由 Chris Matts 提出, 它的意思是推迟决定,直到最后责任期。

Option 在经济领域有期权的意思, 之前了解过一点期货,现在发现,一点都没了解。

Option 给了你一种可能性, 可以以现在的价格去买未来某个时间的商品,也可以不买。

举个例子, 想象你在未来的三个月里很可能会用到大量的铁, 铁的价格在升高。你不想现在买,因为你不是完全确定,预期三个月后才确定。但是如果再等几个月,铁的价格就涨上去了。为了解决这个困境,你可以以今天的价格购买一个期权来在未来三个月后购买铁。如果铁的价格张了,到时候仍然可以以今天的价格买了。如果价格跌了,或者不需要了,可以选择不是用这个期权。你需要为这个期权付钱,但是只是这些铁的总价的一部分: 这是值得的, 因为它让你直到你确认需要它时才决定是否购买。(这是期权的意义,但是之前了解的时候这个都没有了解到,只以为它就是人们炒钱的东西,当然可能大部分都是为了炒钱吧)

生活中也有这个原则的例子。比如你想买个两个月后的机票, 但是你不确定能不能去,这时候一个 600 的票不能退,另一个700的票可以退, 这时候如果自己取得概率是 50%,那就要买那个贵的,这样多花了 100, 如果去,那就的确多花了 100, 如果不去, 都退, 那就相当于少损失 600。

Real Options 是对这个原理的应用。 Chris 总结了这个原理:

  1. 选项有价值
  2. 选项会过期
  3. 在知道为什么了再做决定行动

下面详细来说明

选项有价值

选项是有价值的,因为它们允许你推迟做决定,直到了解的足够多了在决定,这时候成功的概率就更高了。在金融业,股权的价值可以被精确的计算,但是在软件领域,是不可能的。但是,通常你对一个特定的问题直到的可选项越少,保持的你的选项开放就越有价值。

比如, 你为一个年轻的创业公司制作网站。它们不知道它们的用户体量会是多大。他们直到一开始可能很小,但是它们期望一年后会有数百万用户。

你有三个选择:

  • 没有扩展性, 这样,如果达到了百万用户,应用个的架构就需要重构,会是个很大的花费
  • 创建可扩展性, 但是如果体量上不去,就有点浪费了
  • 你不去立刻实现一个完全可扩展的架构,但可以在一开始的时候花点时间考虑可扩展性。如果以后不需要扩展,则只浪费了一点调研的时间,如果需要扩展,则可能花更少的费用实现扩展。

选项会过期

有交付日期,肯定会有过期, 实现功能是需要时间的, 比如 A 需要 5 天, B 需要 3 天, 如果离交付还有 4 天, 那 A 这个选项就不是个选项了。

在知道为什么了再做决定行动

推迟,并不是推迟到截止日期, 而是说当你了解了足够的信息再做决定, 比如两个同样功能的库, 要对每个做调研,了解清楚了再决定选择哪一个。

Deliberate Discovery

在开发中, 最大的一个风险就是忽视, 所以在开始之前一定要做深入调研,广泛调研,避免忽视一些高效的方法。

Real Options 帮助你保持选项开放,直到掌握了足够的信息。Deliberate Discovery则帮助你获取这些信息。

从 examples 到应用: 预览一下

总结

BDD 的主要优势在于:

  1. 对业务的交流沟通
  2. 使用用例去驱除假设,构造对问题空间的统一理解。