从网易笔试题看视频编解码核心知识点与RK3588实战
2018年那会儿网易这套实习生笔试题在圈子里流传得挺广不光是冲着网易去的同学会刷一遍很多准备音视频岗位面试的人都会拿它当试金石。我当时也看过这套题印象最深的是它不考“你用过什么工具”而是把一堆协议层的东西铺开让你在纸面上推演。这跟很多人对“开发岗笔试”的预期不一样——以为会考FFmpeg命令、考API调用结果卷子上一大半是H.264的NALU类型、B帧参考关系、时间戳同步这类原理题。把这套题掰开揉碎之后你会发现它其实在说一件事视频编解码这个岗位招的不是熟练工而是底子扎实、能看懂协议、能理解硬件行为的人。这篇文章我就以这套笔试为引子把题目背后真正想考察的知识点拆开讲一遍最后再聊到rk3588这类硬件平台看看从笔试到真实项目到底有多远。1. 这道笔试到底在筛选什么样的人1.1 岗位画像实习生不是用来干活的是用来培养的网易当年做音视频的摊子铺得很大云音乐要处理音频编解码和网络传输云信要给IM做实时音视频通话CC直播要解决推流、转码、低延迟播放。这几个业务线对视频编解码人才的需求是同一个逻辑要有人能看懂码流结构能定位花屏、卡顿、音画不同步的问题能在硬件编解码器和开源方案之间做取舍。但实习生这个层级没人指望你上来就能改x264的码率控制也没人指望你能独立调通一条硬编链路。笔试的定位是筛选“有没有在这个领域长期积累的潜力”。所以你会发现这套题目的风格很“学院派”——基础理论、协议结构、数学原理占大头工具链知识反而少。这说明命题人想找的是那种拆开一个MP4文件不会慌、看到SPS/PPS能说出含义、理解GOP为什么是50的人。1.2 命题的三个层次协议、工程、思维把整套题看下来基本可以分成三个层次。第一层是协议基础比如H.264的NALU类型怎么区分、SPS和PPS各自存什么、I/P/B帧各自有什么作用、GOP长度会影响什么。这一层考的是“你知不知道编码器在干什么”。第二层是工程细节比如YUV420和NV12的内存排布有什么不同、DTS和PTS的区别是什么、音视频同步有哪几种策略、封装格式里的关键帧索引怎么组织。这一层考的是“你能不能跟播放器、跟渲染器、跟硬件对接”。第三层是思维深度比如码率控制算法在CBR和VBR之间如何取舍、去块滤波的作用是什么、如何判断一个卡顿是网络问题还是解码性能问题。这一层考的是“遇到问题时你会不会排查、会不会做技术选型”。三层下来基本就把“会用”和“懂行”区分开了。我当时批过类似的卷子很多人第一层能拿满分第二层开始掉链子第三层基本上空白。这个分布其实很真实——学校教了多少、自己钻了多少一测就出来。1.3 这套卷子的整体节奏如果按题目类型划分这套笔试题大概有下面几类概念题H.264与H.265的差异、帧类型判断、参考帧的作用计算题码率与文件大小的换算、GOP大小与I帧间隔的关系流程题解码器的完整工作流程、推流拉流的主要环节场景题花屏、卡顿、音画不同步各自优先排查什么比重上概念题和流程题占了大头场景题是拉分项。这说明笔试不是想难倒你而是想看看你对这个领域有没有“感觉”。有感觉的人看到场景题会自然地往协议、缓冲、时间戳这些方向想没感觉的人只会写“可能是网络不好”。2. 从一道真题看编解码基础理论的分量2.1 H.264/H.265的编码骨架如果没有意外这套卷子的第一道大题多半会落到H.264的编码框架上因为它决定了后面所有题目的语境。H.264的核心思路是混合编码空间上用帧内预测去掉图像内部的冗余时间上用帧间预测去掉帧与帧之间的冗余然后对残差做变换、量化、熵编码。笔试里常考的是把这条链路按顺序写出来或者给几个步骤让你排序。有一次我看到一个同学的答案是“量化→变换→预测→熵编码”把变换和量化换了位。这个错误非常典型因为很多人背流程的时候只记名词不理解为什么先变换再量化。实际上变换是把像素域的残差转换到频率域让能量集中到低频系数上量化才是真正丢信息的那一步。先量化再变换的话量化引入的误差会被变换放大重建质量会明显变差。H.265在这个框架上做的主要是两件事一是把宏块扩展成更大范围可选的编码树单元CTU让大块平整区域用更少的比特表示二是增加了更多帧内预测方向和更灵活的参考帧管理。笔试如果问你“H.265相比H.264为什么能省一半码率”答案颗粒度不能停在“算法更先进”要落到具体机制上更精细的帧内预测、更灵活的块划分、更高效的变换和熵编码。2.2 I/P/B帧与GOP结构必须答到参考关系这一层帧类型这张牌基本是视频编解码笔试的必考题。大多数人的认知止步于“I帧是关键帧P帧是预测帧B帧是双向预测帧”但这个答案在网易这套题里只能拿一半分。真正能拉开差距的是下面几个层次第一层I帧可以不依赖任何其他帧独立解码所以它是随机接入点也是GOP的起点。第二层P帧参考前面的帧可以是I帧也可以是其他P帧所以参考帧的管理不是简单“参照上一帧”。第三层B帧同时参考前向和后向的帧这带来一个反直觉的结果B帧的显示顺序和解码顺序不一致。笔试经常给出一串帧的编码顺序让你写出显示顺序或者反过来。这题难倒过很多人因为它需要你理解解码器必须先把B帧的后向参考帧解码出来才能解码B帧。所以码流里的帧顺序是“I P B B P”这样的排列而显示时又要按PTS重新排回“I B B P”。不理解这一层的人遇到多B帧的情况基本就乱了。GOP结构的考察点则在于I帧间隔。GOP越短随机接入越方便但码率越高GOP越长压缩效率越好但遇到丢包时错误扩散的范围也越大。网易那道题我记得是分析一个GOP为50的场景丢了一个P帧后面的帧会花到什么程度。答案不是“全部花掉”而是要看这个P帧有没有被后续帧参考。如果它只是被邻近几个帧参考错误扩散到下一个IDR帧之前就会终止。这个分析过程考察的就是对参考链路的理解而不是死记硬背。2.3 关于SPS/PPS和NALU的考察H.264的码流由NALU组成其中SPS和PPS是非常容易考的概念。SPS存的是分辨率、帧率、参考帧数量这些序列级参数PPS存的是熵编码模式、片组映射这些图像级参数。它们之间的关系可以类比为SPS是全局配置PPS是单张图像的配置。笔试题的常见变形是给你一段十六进制的NALU头让你判断它是什么类型。NALU头的一个字节里低5位就是类型值1是非IDR的片5是IDR片7是SPS8是PPS。这个知识点本身不难但很多人只记类型编号不记背后的结构。我建议准备笔试时把这个知识点跟实际抓包结合起来理解——用工具打开一个H.264裸流你会看到每个关键帧前面都跟着SPS和PPS这就是解码器初始化的依据。没抓到SPS/PPS直接给片数据解码器无从下手这在RTP推流场景里是一个真实存在的坑。3. 工程落地方向解码器结构、像素格式、封装与同步3.1 解码流程笔试填空题背后是一条流水线解码器的工作流程也是这套卷子的常客而且通常用填空题或排序题来出从码流中提取NALU→解析SPS/PPS→对片数据进行熵解码→反量化→反变换→帧内/帧间预测补偿→去块滤波→输出YUV帧。这个流程看起来是死记硬背实际上每一步都对应一个真实的问题域。比如“熵解码拿到的是什么”答案是量化后的变换系数和运动矢量“反量化为什么会有精度损失”因为量化步长本身就是有损的“去块滤波为什么放在最后而不是放在预测之前”因为滤波要基于重建帧来做顺序反了会导致环路漂移。帧内预测这一步值得多说一点。H.264的帧内预测有9种方向模式核心思路是用周围已重建像素去预测当前块然后只编码残差。笔试会问你“为什么帧内预测用的是重建像素而不是原始像素”答案是为了保证编码端和解码端的预测一致。如果用原始像素做预测解码端拿不到原始像素两边预测不一致误差会累积。这个细节能看出一个人有没有真正跑通过编码器。3.2 像素格式从YUV420到NV12/NV21视频编解码离不开像素格式尤其是YUV家族。笔试常考的是YUV420为什么比RGB444省一半存储以及NV12和NV21的区别。YUV420的意思是亮度Y每个像素都保留色度U和V每四个像素共享一对也就是水平方向各采样一半、垂直方向各采样一半。一个1920x1080的帧Y分量是1920x1080个字节U和V各是960x540个字节总共是1920x1080x1.5个字节。相比RGB888的1920x1080x3个字节正好省一半。NV12和NV21的区别在于UV的排列顺序NV12是UV交错、U在前NV21是VU交错、V在前。这个在Android平台和rk3588的硬件编解码器上特别重要因为不同硬件模块默认输出的格式不一样。rk3588的VPU解码输出通常是NV12但如果你要在OpenGL里做渲染可能需要转成RGBA或者直接在shader里处理NV12的两个plane。笔试不会考到这么细但会问“NV12和I420的区别”实际上就是UV是交错排列还是分开排列。这题丢分的人不少因为平时写代码直接调接口格式转换都封装好了很少有人会关注内存布局。但做视频开发格式转换是最容易踩坑的地方——分辨率对了、格式不对画面就是绿油油一片或者颜色错乱。3.3 DTS/PTS与音视频同步场景题的重灾区时间戳是笔试和面试都绕不开的点。DTS是解码时间戳PTS是显示时间戳。在有B帧的视频流里两者的顺序不同在音频流里因为不存在B帧两者通常相同。笔试的出题方式一般是给你一组视频帧的PTS和DTS问播放器应该按哪个时间戳排显示顺序。答案是PTS。解码器按DTS顺序解码但视频渲染必须按PTS顺序把帧交到屏幕上。如果直接按DTS显示B帧就会在时间轴上乱掉画面会出现“倒放”一样的诡异效果。音视频同步是场景题的重头。常见的同步策略有三种以音频为主时钟、以视频为主时钟、以外部时钟为主时钟。实际产品里绝大多数选择以音频为主时钟因为人耳对音频卡顿更敏感而视觉可以容忍一定程度的丢帧或重复帧。答题的时候如果能补充一句“要定期校准主时钟因为晶振漂移会导致长时间播放后累积偏差”这个答案的含金量会明显上一个台阶。网易那套题里有一道场景题说的是播放一段时间后音画开始不同步让你列出排查思路。合理的链路是先看时间戳在源头是否正常生成再看网络传输是否引入抖动然后看解码器的缓冲策略是否丢弃了过多数据最后看渲染环节是否有重复帧。每一步背后都有对应的工具和日志能写出这条链路的人看问题的方式已经是工程化的了。4. 码率控制与画质优化面试官真正想听到的回答4.1 码率控制算法怎么答才不会显得外行码率控制是最容易考到、也最容易答得空泛的主题。如果你只写“CBR是固定码率VBR是可变码率”那基本只能拿基础分。这道题想听到的是你理解两种模式各自的适用场景和代价。CBR固定码率适合带宽受限的场景比如直播推流、视频会议它的特点是输出码率稳定但代价是画面复杂度高时质量下降复杂度低时浪费码率。VBR可变码率适合存储类场景比如点播文件的离线转码它允许在复杂场景多用码率在简单场景少用所以在同等平均码率下画质更好但峰值码率可能很高不适合实时传输。中间还有一个ABR平均码率它试图在两者之间找平衡允许短期码率波动但长期平均保持稳定。这个在直播平台经常用作“目标码率上下限约束”的实现方式。答题时如果能补充一句“码率控制本质上是一个比特分配问题难点在于如何预估当前帧的复杂度”这个理解高度就出来了。框架层面x264和x265都是通过调节量化参数QP来控制输出码率QP越大细节丢得越多、码率越低。恒定质量模式CRF就是固定一个目标QP让编码器自己浮动码率而ABR模式则是通过反馈控制不断调整QP来逼近目标码率。4.2 码率、分辨率、帧率的关系记一个快速估算公式笔试计算题里常出现“一个1080p30的视频码率4Mbps录1小时有多大”这类题。计算方式不复杂4Mbps 4,000,000 bps换算成字节要除以8得500,000 B/s一小时就是500,000 x 3600 1.8GB。如果用MB来算大约是1716MB也就是1.68GiB。这里有个坑视频领域经常混用Mbps和MB/s题干给的是Mbps算文件大小必须先除8再乘时间。不少人在这里把十进制和二进制又搅和一遍算出来差好几个百分点。反向的题目也常出给你一个文件大小和时长反推平均码率。这个思路要记住一个公式码率(kbps) 文件大小(KB) x 8 / 时长(秒)。如果算出来码率高得离谱那播放时大概率会卡顿因为实际网络带宽跟不上码率太低画质又会明显下降。对于H.264业界有一个粗糙的经验值1080p视频中高画质大概需要4-8Mbps720p大概2-4Mbps。H.265可以在这个基础上省一半左右。笔试问到“为什么同样的码率H.265画质更好”答案要落到编码效率上而不是简单地“算法更先进”。H.265以更细的块划分和更灵活的运动补偿为代价换来了更高的压缩率代价是编码复杂度翻了几倍。4.3 客观指标与主观画质如何向面试官展示调优思维画质评价通常分客观和主观两条路。客观指标里最常见的是PSNR和SSIM。PSNR基于像素级的均方误差数值越高说明失真越小但它的缺陷在于对人眼感知不友好——有些PSNR很高的图像看起来反而比PSNR稍低的更“脏”。SSIM则从亮度、对比度、结构三个维度计算相似度比PSNR更贴近主观感受。面试如果聊到画质优化最好的回答是给一个具体场景。比如直播场景中运动剧烈画面和人脸特写的码率分配策略就应该不同人脸区域值得多分一点码率因为人对人脸细节很敏感静止背景可以大胆用较大的QP。这种“根据内容特性分配比特”的思路比强调“我调了很多参数”有说服力得多。笔试不太可能让你现场调编码器但它可能给你一组不同QP下的文件大小和PSNR让你分析趋势。这时候要能说出QP从20提到40文件大小指数级下降但PSNR不会线性下降因为自然图像的能量集中在低频量化掉高频分量对主观观感的影响可能小于码率省下来的收益。能说出这一层说明你不是单纯背概念而是理解率失真优化的基本逻辑。5. 从笔试题到rk3588硬件编解码时代的变化5.1 这套笔试题里的知识在rk3588上全都用得着rk3588是瑞芯微的旗舰平台视频编解码能力很突出支持8K60fps的H.265/VP9/AVS2解码、8K30fps的H.265/H.264编码。这个能力在嵌入式平台上算天花板级别了所以很多人拿到RK3588的开发板第一件事就是测它的编解码性能。有意思的是如果拿着2018年网易那套笔试题去对照rk3588的开发过程你会发现题目里的概念几乎每个都会用到。比如你调用MPP库解码一个8K视频时你先要解析的还是SPS/PPS你需要确认解码输出的像素格式是NV12还是NV21你往编码器喂帧的时候还是要根据PTS决定显示节奏。协议的东西不会因为硬件换代就失效变化的只是实现方式。5.2 硬编解与软编解的差异笔试不会明说但面试会问笔试可能会问“什么是硬解码、什么是软解码”但面试往往会追问“你们项目里为什么选硬解不选软解”。软解是用CPU跑开源库比如FFmpeg配合libx264/libx265优点是灵活、更新快、参数可控缺点是CPU占用高、功耗大。硬解是用芯片里专用的编解码单元VPU处理优点是速度快、功耗低、CPU几乎不参与缺点是格式支持取决于硬件而且参数调节空间小。在实际项目中做选型时核心就一句话“如果你的平台对功耗和实时性有要求优先硬编解如果你的产品需要频繁更新编码算法或者做实验性调优直接用软件方案。”rk3588上跑8K视频软解基本是不现实的CPU会直接被吃掉一大半硬解则可以做到几十毫秒解一帧CPU占用很低。还有一个常见考点是“硬解和软解的解码结果有什么不同”。实际上两者的输出都是YUV帧理论上应该一致但因为去块滤波、参考帧管理等细节实现有差异硬解和软解在同一码流上可能产生极细微的像素差异这个在正常使用中感知不到。真正需要注意的差异是硬解对码流的容错能力通常弱于软解遇到格式不规范、SPS参数怪异的码流软解可能还能出图硬解很可能直接报错或者黑屏。5.3 MPP库基本流程理解原理后很好上手rk3588的硬件编解码离不开Rockchip的MPP库。它的基本流程是这样的先创建上下文MppCtx再配置解码/编码参数比如分辨率、格式、码率模式然后循环地往输入队列里丢数据包、从输出队列里取帧。解码侧的关键是理解“输入包与输出帧不是一一对应”这件事。因为存在B帧重排而且解码器内部会有缓冲你喂进去三四个数据包可能才出来一帧或者一个数据包解出多帧。如果按照“喂一包收一帧”的同步思维去写很容易卡死。编码侧的关键是设置好GOP和码率控制参数。rk3588的MPP支持CBR和VBR模式对实时流场景一般用CBR并设置一个合理的码率对录制场景可以考虑VBR来保画质。另一个容易出问题的是帧率控制——如果你没有按实际帧率喂帧编码器生成的码流时间戳就会乱播放器会出现快放慢放。我见过很多人拿到rk3588开发板后直接把官方demo里的GOP和码率参数原样用结果在直播推流时频繁花屏。原因就是那个demo是为本地录制设计的GOP很大、码率控得很准但网络传输遇到丢包时错误扩散范围太大。把GOP调短到比如两秒一个IDR帧同时把码率冗余留出10%-20%花屏概率会大幅下降。这里面的分析思路跟前面讲的GOP长度对错误扩散的影响完全一样——笔试里的概念在实战里直接变成了一个可执行的调优手段。5.4 从纸面到真机时间戳和像素格式依然是翻车重灾区最后说一个我在rk3588平台上的真实经历。有一次做8K视频解码显示画面出来了但颜色明显发绿且偶发性音画不同步。排查后发现是两个独立的坑叠加在一起。颜色发绿是因为GPU渲染时把NV12的两个plane当成了连续内存处理但MPP解码输出时Y平面和UV平面之间的stride不连续导致UV数据读错了位置。解决办法是先获取drm buffer的信息按正确的offset和stride去映射显存而不是想当然地按宽度乘高度算偏移。音画不同步是因为我在丢帧策略上做了“解码丢帧”但音频还在按原始PTS播放。解码丢帧会改变视频帧的显示节奏后续所有帧的PTS对不上音频偏差会越来越大。后来改成“渲染丢帧”也就是解码照常进行但在显示前判断是否逾期只丢赶不上显示时间的帧同步就恢复了。这两个问题单看任何一个都可以回到2018年那套笔试题的知识点上像素格式决定你怎么处理解码输出时间戳决定你如何做同步。只不过笔试考的是概念真机调的是bug。我的经验是准备这类笔试时不要只刷题最好手头有一套能跑的编解码环境。哪怕是拿FFmpeg命令行做实验把一段视频分别用不同GOP、不同码率转码再对比输出文件的大小和播放体验你对“GOP影响什么、码率影响什么”的理解都会比死记硬背深得多。等你拿到rk3588这类硬件平台时再用MPP库的example跑一遍解码、编码、显示全链路笔试里那些名词就真的变成了你手里的工具。