webrtc源码阅读理解一
webrtc是一个比较成熟的实时音视频处理开源项目,一上来老大就扔给我一本webrtc native实践,虽然狠下心“翻”完了一遍,但是还是云里雾里的,在经过几个月的摸索之后,我大概知道原因了,归根到底,是基础不在一个层次,理解不了的,所以我决定,尝试写一个接近我这种零基础入门实时音视频的记录系列,希望能帮到一些同学
基础概念的理解
实时音视频是一个很长的流程,从采集-编码-传输-接收-解码-渲染,每一个步骤都是很大的模块,所以我们一个一个来,我们先从采集相关的设计开始,我们先看一些概念,否则直接看代码会有点懵
stream(流):包含音频轨和视频轨的编码流
track(轨道):音频轨或者视频轨
音视频同异点-我的理解
先说几个点
- 音频和视频还是很多地方不一样的
- 音频采集了,自己不不要同时听到自己,一般只需要传输给对方;一般只有一个采集的地方;即使有多个采集的地方,对方希望听到是合流之后的一个声音;
- 视频采集了,一般需要同时在己方和对方都渲染显示出来;可能要多个采集源;一般希望每个视频源独立展示(甚至是不同的设备展示)
- 音频和视频有很多地方是一致的
- 是同级的概念;整体的处理流程几乎一致
- 音频和视频输入和输出的过程不一样
整体感觉是视频的逻辑要比音频复杂一些,所以下面我主要也是围绕视频展开,音频也会顺便说下
视频代码设计
其实这个地方很难真正从零开始,我这里也是从中间某个点开始说(对着代码说自己的理解);结合上面的同异点,我们来看下webrtc里面的代码设计
source和sink
这是我觉得第一个坑的设计,但你理解了之后,觉得这样设计也没有问题

联系实际场景,摄像头采集到图像之后,保存视频,成为视频源,编码和本地渲染需要消费图像做处理,类似于生产和消费的概念
对于消费者,也就是sink来说,如果我想要增加一个消费者,我继承sink接口,塞到保存视频源的实例里面去,让实例不断给我塞数据给我消费即可(onFrame),所以sink的接口定义比较好理解;
source的接口定义里面只有对sink的操作,这是我觉得一开始不好理解的地方,source并没有存储视频图像(为什么叫source呢?);我现在的理解是,相对于sink,这样的接口就可以理解为source(摄像头采集图像之后,调用source的某个接口,这这个接口里面,对图像数据进行分发给sink,对于sink来说,这个实例就可以理解为source);
videoBroadcaster
broadcaster做的就是我们上面那段话想做的事情
source的接口太简单了,下面是videoSourceBase的函数定义,还增加了一个sinks的成员来保存所有的sink成员;
而broadcaster同时继承了sink和source,这就是我们想做的事情:初始化一个broadcaster实例,增加一个消费者sink的时候,把sink通过broadcaster的source接口存入sinks即可;当采集到图像的时候,把图像按照既定的逻辑调用所有sink的接口即可;


webrtc里面同时是sink又是source的实例还有很多,例如
这是第一个实际概念到代码设计的实践,可以看到,简单的物理概念想真正用代码设计构架起来,还是需要很多抽象设计和构架思考的
source、track、stream
上面说完了整体一个大概念的图像采集之后,采集分发的小流程,这些图像数据source要变成track最后要形成 stream,我们看下这里的设计,在这些之前,有些更细节的概念也要考虑到,例如音视频发生了变化需要通知观察者
所以首先定义了观察者接口和通知者接口,都是很纯粹的接口定义

而通知者的继承关系则很长,通知接口有三个继承者MediaSourceInterface,MediaStreamTrackInterface,MediaStreamInterface,基本source、track、stream都是通知者

MediaSourceInterface
定义了媒体源的基本状态,媒体大类有两个,音频和视频,所以有两个继承者VideoTrackSourceInterface,AudioSourceInterface,上面也说到过,音视频细节上有些差异,从这里的接口设计可以看到一些

AudioSourceInterface
AudioSourceInterface的接口,例如音量这些,都是音频独有的

VideoTrackSourceInterface
因为之前已经定义了VideoSourceInterface,所以这里直接到了videoTrackSource的定义

从audio和video两个继承来看,这里的分化挺明显的
MediaStreamTrackInterface
track的定义和继承如下,定义了trackState和必要接口;同时可以看到有音视频track两个子接口

videoTrack

audioTrack和VideoTrack有一个不一样的地方是,audioTrack只是组合了audioSource,videoTrack还继承了videoSource,我理解这是因为视频的来源和分发比音频复杂,因为所有的音频可能最后会汇聚成一个,是多个视频源可能需要分发和处理到不同的地方;

MediaStreamInterface
最后继承Notifier的是MediaStreamInterface,可以看到,stream是videoTrack和audioTrack的组合

好了,今天就先写到这里,后面应该会持续更新
p
webrtc源码阅读理解一的更多相关文章
- Mask RCNN 源码阅读(update)
之前看了Google官网的object_dectect 的源码,感觉Google大神写的还不错.最近想玩下Mask RCNN,就看了下源码,这里刚好当做总结和梳理.链接如下: Google官网的obj ...
- JDK 1.8 源码阅读和理解
根据 一篇文章教会你,如何做到招聘要求中的“要有扎实的Java基础” 的指引,决定开始阅读下JDK源码. 本文将作为源码阅读总纲 一.精读部分 java.io java.lang java.util ...
- JDK部分源码阅读与理解
本文为博主原创,允许转载,但请声明原文地址:http://www.coselding.cn/article/2016/05/31/JDK部分源码阅读与理解/ 不喜欢重复造轮子,不喜欢贴各种东西.JDK ...
- 1.4、WebRTC源码
文章导读:本篇文章给读者展示WebRTC的源码目录结构,为读者构建全方位的知识体系,如果你有兴趣下载webrtc的源码来编译运行,本节内容可以作为你了解源码的简要说明书,webrtc源码非常庞大的,讲 ...
- 【原】AFNetworking源码阅读(六)
[原]AFNetworking源码阅读(六) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 这一篇的想讲的,一个就是分析一下AFSecurityPolicy文件,看看AF ...
- 【原】AFNetworking源码阅读(五)
[原]AFNetworking源码阅读(五) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 上一篇中提及到了Multipart Request的构建方法- [AFHTTP ...
- 【原】AFNetworking源码阅读(四)
[原]AFNetworking源码阅读(四) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 上一篇还遗留了很多问题,包括AFURLSessionManagerTaskDe ...
- 【原】AFNetworking源码阅读(二)
[原]AFNetworking源码阅读(二) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 上一篇中我们在iOS Example代码中提到了AFHTTPSessionMa ...
- 【原】AFNetworking源码阅读(一)
[原]AFNetworking源码阅读(一) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 AFNetworking版本:3.0.4 由于我平常并没有经常使用AFNetw ...
随机推荐
- 见微知著 带你透过内存看 Slice 和 Array的异同
hi, 大家好,我是 hhf. 有这么一个 Go 面试题:请说出 slice 和 array 的区别? 这简直就是送分题.现在思考一下,你咋样回答才能让面试官满意呢? 我这里就不贴这道题的答案了.但是 ...
- 【设计模式】装饰者模式(DecoratorMode0
From: https://liudongdong1.github.io/ 装饰者模式(Decorator Pattern):动态地给一个对象增加一些额外的职责,增加对象功能来说,装饰模式比生成子类实 ...
- shell 函数返回值与字典
shell的函数只能返回整数值,如果想让函数返回字符串可以在函数调用处为变量赋值. # 定义函数function test() { name=$1 echo "123213" } ...
- Spring整合Quartz轻松完成定时任务
一.背景 上次我们介绍了如何使用Spring Task进行完成定时任务的编写,这次我们使用Spring整合Quartz的方式来再一次实现定时任务的开发,以下奉上开发步骤及注意事项等. 二.开发环境及必 ...
- iphdr结构
包含在/usr/src/linux/include/linux/ip.h 1 struct iphdr { 2 #if defined(__LITTLE_ENDIAN_BITFIELD) 3 __u8 ...
- Git撤销&回滚操作(git reset 和 get revert)
转自:https://blog.csdn.net/asoar/article/details/84111841 git的工作流 工作区:即自己当前分支所修改的代码,git add xx 之前的!不包括 ...
- Git修改历史commit的author信息
前言 "嘀嗒嘀嗒",抬头看向墙上的钟表,此时已是凌晨1点.小明终于把Go语言圣经第二章的笔记写完,保存commit,提交,然后睡觉. 额,等等,不对,小明发现他用的是公司的git账 ...
- Java - 记录01_开发环境搭建
时间:2017-07-04 记录:byzqy 一.什么是JDK JDK(Java Development Kit):Java开发工具集,即Java语言的软件开发工具包. SDK(Software De ...
- 并发编程之:Lock
大家好,我是小黑,一个在互联网苟且偷生的农民工. 在之前的文章中,为了保证在并发情况下多线程共享数据的线程安全,我们会使用synchronized关键字来修饰方法或者代码块,以及在生产者消费者模式中同 ...
- idea字节码插件JClassLib——阅读JVM字节码
idea字节码插件JClassLib--阅读JVM字节码 生成字节码文件并查看 查看字节码文件的方式:javac 文件名.java 即可生成.class文件,但是这种方式不方便 java:是运行字节码 ...