科技 > 软件教程 > 媒体工具

FFmpeg开发笔记(三十)解析H.264码流中的SPS帧和PPS帧

75人参与 2024-08-04 媒体工具

《ffmpeg开发实战:从零基础到短视频上线》一书的“2.1.1  音视频编码的发展历程”介绍了h.26x系列的视频编码标准,其中h.264至今仍在广泛使用,无论视频文件还是网络直播,h.264标准都占据着可观的市场份额。

之所以h.264取得了巨大的成功,是因为它提出了一个新概念,把标准框架划分为两个层面,分别是视频编码层(video coding layer,简称vcl)和网络抽象层(network abstraction layer,简称nal,也称网络提取层)。其中视频编码层专注如何高效地表达视频的数据内容,而网络抽象层负责格式化数据并提供头信息,以便视频内容能够适应各种环境的数据传输。
每个视频帧都包含至少一个nal单元,对于i帧、p帧来说,因为内部数据比较多,所以可能会分为多个nal单元。各帧的第一个nal单元以起始码0x00000001开头,表示从这里开始是一个新帧;从第二个nal单元开始,后继nal单元以0x000001开头,表示其后数据是前面nal单元的接续。
起始码往后的一个字节,代表当前帧的类型,常见的帧类型有下列六种:
0x67,类型值为7,为sps帧,表示序列参数集。
0x68,类型值为8,为pps帧,表示图像参数集。
0x65,类型值为5,为idr帧,即idr图像,也称为关键帧。
0x41,类型值为1,为slice分片,表示p帧。
0x01,类型值为1,为slice分片,表示b帧。
0x06,类型值为6,为sei帧,表示辅助增强信息。
在上述六种类型的nal中,前三种是必不可少的,分别详细说明如下。

一、sps帧

sps的全称是sequence paramater set,中文叫作序列参数集。sps保存着视频内容的规格参数,包括视频高度、视频宽度、帧率等等。sps的详细格式在h.264标准协议中(文档的7.3.2.1部分)规定,内部各字段的取值情况如下图所示。

根据sps的字段定义,得到视频宽高的计算式子如下:

width = ((pic_width_in_mbs_minus1 +1)*16) - frame_crop_left_offset*2 - frame_crop_right_offset*2;
height= ((2 - frame_mbs_only_flag) * (pic_height_in_map_units_minus1 +1) * 16) - (frame_crop_top_offset * 2) - (frame_crop_bottom_offset * 2);

当视频宽度和视频高度均为16的整数倍时,frame_crop_left_offset、frame_crop_right_offset、frame_crop_top_offset、frame_crop_bottom_offset这四个字段值均为0,且frame_mbs_only_flag字段值为1。此时视频宽高的计算式子简化如下:

width = (pic_width_in_mbs_minus1+1)*16;
height = (pic_height_in_map_units_minus1+1)*16;

除了视频宽高,通过sps内部字段还能计算视频的帧率,帧率的计算式子如下:

fps = time_scale / num_units_in_tick;

二、pps帧

pps的全称是picture paramater set,中文叫做图像参数集。pps保存着视频帧的编码参数,包括熵编码模式、切片分割类型、初始量化参数、色度量化参数等等。pps的详细格式在h.264标准协议中(文档的7.3.2.2部分)规定,内部各字段的取值情况如下图所示。

三、idr帧

idr的全称是instantaneous decoding refresh,中文叫做立即解码刷新。idr一定是i帧,但i帧不一定是idr。一旦出现idr,就表示清除前面的序列,并且立刻渲染当前的idr帧。
在每个h.264流的开头,都会出现这样的序列:sps帧→pps帧→idr帧→其余slice,并且sps、pps、idr三种帧必定是搭配出现的,缺一不可,如果少了其中任何一帧,都会导致后续视频流解码异常。

更多详细的ffmpeg开发知识参见《ffmpeg开发实战:从零基础到短视频上线》

(0)
打赏 微信扫一扫 微信扫一扫

您想发表意见!!点此发布评论

推荐阅读

FFmpeg开发笔记(三十二)利用RTMP协议构建电脑与手机的直播Demo

08-04

FFmpeg开发笔记(十九)FFmpeg开启两个线程分别解码音视频

08-04

FFmpeg开发笔记(三十七)分析SRS对HLS协议里TS包的插帧操作

08-04

FFmpeg开发笔记(十四)FFmpeg音频重采样的缓存

08-04

FFmpeg开发笔记(三十八)APP如何访问SRS推流的RTMP直播地址

08-04

FFmpeg开发笔记(十二)Linux环境给FFmpeg集成libopus和libvpx

08-04

猜你喜欢

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论