百度视频云音视频高级研发工程师——面经
自学音视频技术差不多1年,有点飘了。在bos s上挂了简历,有幸被百 度的HR看到。我跟HR说:我只能达到初/中级水平,达不到高级水平。HR说没事:投个简历吧。 我猜她是为了完成指 标,那就成 全她。投了简历,然后安排了面试。特此凭着记忆,记录一下面试过程。
首先自我介绍:上学、工作、项目。 对于自己特别熟悉的,拿手的,一定要重点多说一些,其他的,不熟悉的,一带而过。我是傻傻的,没有区分重点难点,一溜烟介绍了。而且自己做的项目,一定要特别熟悉,内部啥原理,甚至代码细节,都会被问到。 我这个人有个习惯:碰到不懂的,当时查清楚了,并记录了笔记CSDN/ github。结果东西就没有记在脑子里,脑子里记的,只有问题以及这个问题去哪里找答案。 看来,脑子只存储了指针。
1、全局变量,需要volatile关键字修饰。每次从内存中去读这个值。
定一个全局变量,通过改变全局变量,通知线程做相应的动作,比如:bool类型的,就是通知线程是否停止退出。
如果不加volatile 关键字,直接使用全局变量,会有什么问题?
volatile 关键字声明变量,可以用于两个线程通信。当两个线程都要用到某一个变量且该变量的值会被改变时,应该用 volatile 声明,该关键字的作用是防止优化编译器把变量从内存装入 CPU 寄存器中。如果变量被装入寄存器,那么两个线程有可能一个使用内存中的变量,一个使用寄存器中的变量,这会造成程序的错误执行。volatile 的意思是让编译器每次操作该变量时一定要从内存中真正取出,而不是使用已经存在寄存器中的值。
2、临界区域
CRITICAL_SECTION section;// 临界区对象
InitializeCriticalSection(§ion);// 用之前,必须初始化
EnterCriticalSection(§ion);// 进入临界区,获取所有权
LeaveCriticalSection(§ion);// 释放所有权
需要了解自动锁,C++11的新标准。
3、互斥量
HANDLE hMutex; // 声明一个互斥量
hMutex = CreateMutex(NULL, FALSE, NULL);//创建,并设置为false,没有线程拥有它
WaitForSingleObject(hMutex, INFINITE);// 某线程,拿到钥匙的使用权。
ReleaseMutex(hMutex);// 使用完之后,要释放线程的使用权
4、事件
HANDLE hEvent; // 事件对象
// 第二个参数:TRUE,表明人工重置对象, FALSE,非人工,即自动重置对象
// 第三个参数:FALSE,表明一开始没有线程拥有这个hEvent;无信号状态
hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
SetEvent(hEvent);// 使得hEvent为有信号状态,其他线程可以取到
WaitForSingleObject(hEvent, INFINITE);// 请求事件对象,将hEvent设置为非信号状态
SetEvent(hEvent);// 将hEvent设置为有信号状态,其他线程可拿去使用
详细描述连接
在H.264/AVC视频编码标准中,整个系统框架被分为了两个层面:
1.VCL (VideoCoding Layer,视频编码层)。核心算法引擎,块,宏块及片的语法级别的定义,负责高效的视频内容表示,通俗的讲就是编码器直接编码之后的数据,这部分数据还不能直接用于保存和网络传输,否则在解析上存在困难。
2.NAL(NetworkAbstraction Layer,网络抽象层)。负责格式化数据并提供头信息,以保证数据适合各种信道和存储介质上的传输,通俗的讲NAL就是将上面的VCL加了一些头部信息封装了一下。
现实中的传输系统是多样化的,其可靠性,服务质量,封装方式等特征各不相同,NAL这一概念的提出提供了一个视频编码器和传输系统的友好接口,使得编码后的视频数据能够有效地在各种不同的网络环境中传输。
最后所有的数据逻辑关系总结如下:
SODB + RBSP trailing bits = RBSP (原始字节序列载荷)
RBSP 将0x0000替换为0x000003 = EBSP
NAL header(1 byte) + EBSP = NALU
Start Code Prefix(3 bytes) + NALU + Start Code Prefix(3 bytes) + NALU + … + = H.264BitsStream
start code 是3位0x000001或4位0x00000001, 3字节的只有一种场合下使用,就是一个完整的帧被编为多个slice的时候。
https://blog.csdn.net/qq_34732729/article/details/104969107
https://blog.csdn.net/qq214517703/article/details/80359911
查看工具:UltraEdit , mp4reader, 查看MP4文件的详细格式。
https://www.cnblogs.com/boonya/p/8572052.html // 从代码层次的分析
https://blog.csdn.net/yue_huang/article/details/72812109 // 从结构方面,文字分析。并且,最后还会有各种计算样例。
进程是系统动态执行的基本单位,也是系统分配资源的基本单位;
线程是进程中执行的最小单位,它可以访问进程的共享资源。
进程之间对共享内存等进行读写操作,需要使用互斥机制,常使用Mutex;进程的同步机制包括Event、Semaphore,常使用Semaphore。进程间的通信不仅包括进程的同步互斥,还包括进程间数据的传输。
进程间常用的通信方式:共享内存、管道、信号量Semaphore、端口,其中Mutex和Event放在共享内存中使用。
Shared Memory称为共享内存,它是进程间数据传输最快的通信方式。由于共享内存是所有进程都可以访问,因此共享内存的操作需要加锁。
pipe称为管道,其分为命名管道、匿名管道。
毕竟音视频是离不开C++的,而且现在C++11的新特性,都是常用的。
C++11的智能指针,比之前的智能指针好在哪里。
这部分就需要去看C++内部是如何构造和实现了。大厂就是问得深!
https://www.dazhuanlan.com/2019/12/05/5de8187dcb7b9/
① url 是资源的地址。www.baidu.com, 域名,相当于一个服务器的别名,而服务器真正的地址是一个ip地址:182.61.200.6。
②任何一个域名首先都会去DNS服务器中 转换一个ip, 只有转换了ip, 才能准确的找到这个服务器。本地有一个hosts文档,内部会存储一些常用的Ip和域名。本地访问的时候,会先去hosts里面找找,没有的话,再去DNS中转换,将转换回来的ip和域名,记录仅hosts文件(注意:hosts文档不是永久存储的,它会存储一段时间之后,里面的存储信息就会失效了。)。
③浏览器向服务器发送请求之前,会先建立一个可靠的TCP/IP连接(三次握手)
④ 浏览器向web服务器发送请求
⑤ web服务器接收并处理请求
⑥ 服务器将数据返回给浏览器
⑧解析HTML、渲染页面(这一块内容较多,暂不记录)
⑦ 断开连接,4次挥手
自己开发了一个录音机,可以录制内部声音和外部声音,所以介绍这个项目的时候,就被问到了。解答: 先安装一个screen capture recorder.exe 的文件,然后在cmd框,输入:ffmpeg -list_devices true -f dshow -i dummy, 就可以看到了virtual-audio-capture。然后写代码的时候,在 avformat_open_input(&pFmtCtx_Audio_in, psDevName, ifmt_audio, NULL),中,用virtual-audio-capture 替换“麦克风阵列”, 就可以采集内部声音了,也就是直接采集声卡。https://blog.csdn.net/qq_34732729/article/details/106573048
mp2: 有损压缩的音频格式。MP2主要应用在标准化数字广播和数字电视广播(DAB,DMB,DVB)的数字音频和视频编码。MP2文件格式通常用于广播电视行业,所以在普通音频播放器上的支持率不高。音质比mp3好。
mp3: 有损压缩的音频格式。压缩比例比MP2大,所以更适合网络传播。
因为简历上写了熟悉Linux,就被问到,在Linux下做过什么。
主要是在本地虚拟机VMware workstation15.5下,安装Ubuntu16.04系统。 通过shell进行操作的。 练习C++编程,学习nodejs,搭建简单的https服务。 编译ffmpeg, 适合android的arm32, arm64, 适合Linux的动态库。 搭建coturn服务,并测试。 搭建nginx服务,作为rtmp推流的服务器 。编译webRTC的android版
RTP | RTMP | |
概念 | Real- time Transport Protocol(实时传输协议) | Real Time Message Protocol(实时信息传输协议) |
协议 | UDP | TCP |
用途 | 在Internet上处理多媒体数据流的传输层协议, 单播(1V1),多播(组播1V多) |
用来解决多媒体数据传输流的多路复用(Multiplexing) 和分包(packetizing)的问题 |
格式 | RTP header + payload | RTMP在收发数据的时候并不是以Message为单位的, 而是把Message拆分成Chunk发送,而且必须在一个 Chunk发送完成之后才能开始发送下一个Chunk。 每个Chunk中带有MessageID代表属于哪个Message, 接受端也会按照这个id来将chunk组装成Message。 |
RTSP发起/终结流媒体、RTP传输流媒体数据 、RTCP对RTP进行控制,同步。
RTSP可以对流媒体提供诸如播放、暂停、快进等操作,它负责定义具体的控制消息、操作方法、状态码等,此外还描述了与RTP间的交互操作(RFC2326)。
1、继承QThread方式:
2、moveToThread方式
work1
对象移到新线程下,完整的:
参考链接
因为2016年用过opencv,打开摄像头,采集图像,然后对图像进行处理:滤波,去除噪点、阈值分割、candy算法提取边缘。 通过像素与实际标定距离的转换,获得实际距离。其实opencv这些年发展应用领域挺广泛的:人机互动、物体识别、图像分割、人脸识别、动作识别、运动跟踪、机器人、运动分析、机器视觉、结构分析、汽车安全驾驶等。
这里介绍项目的时候,一定要熟悉到每一行代码。不然很容易被问懵。千万不要说:就是这样解决的呀,不觉得难呀。。。
二叉树的插入。 我说:这个好难啊。 考官说:那写个双链表的插入和删除吧。 我以为我记得怎么写。 提笔忘字。 没写出来。 还是准备的不够充分。 面试前,一定要写写代码,找找手感,而不是看看代码,背一下。
面试时间70分钟。整个过程满满当当。面试官是一个特别和蔼的技术男。这里的每一个问题,都可以整理一篇博客了。果然是大厂,面试就是认真!