我正在从事一个需要Access units
在H.264
原始基本流中剪切一些的项目,例如删除 4 个访问单元并播放剩余的视频。
为此,我将Access unit Delimiter
( NAL Unit Type:9
) 作为边界Access Unit
并剪切了视频,但视频以丢包结束。但是,如果我以Sequence parameter set
( NAL Unit type :7
) 为边界,则结果视频播放没有任何丢包。
有人请帮我解决这个问题:我应该在哪里剪切视频?
由于您没有更详细地描述您的流,例如存在哪些 NALU 以及此处的内容如何格式化,因此有一些一般准则:
您总是需要 SPS/PPS,因为它们包含如何解码帧的信息。我假设你收到一个附件 B 类型的流,在这种情况下缓存最后一个 SPS/PPS 直到出现新的,用旧的解码剩余的图片,然后应用新的。
如果你有 AUD NALU,那么你已经有了最后一个访问单元的结尾,你可以轻松地分割视频,不需要做太多事情。
如果您需要更深入地挖掘,这里是关于 NAL 单元顺序以及如何检测主编码图片的第一个 VCL NAL 单元的规范摘录。
来自 ITU-T H.264 (05/2013)
7.4.1.2.3 NAL 单元和编码图片的顺序以及与访问单元的关联
本节规定了 NAL 单元和编码图片的顺序以及与编码视频序列的访问单元的关联,这些视频序列符合附件 A 中指定的一个或多个配置文件,并使用第 2-9 节中指定的解码过程进行解码。
一个访问单元由一个主编码图片、零个或多个相应的冗余编码图片和零个或多个非 VCL NAL 单元组成。VCL NAL 单元与主要或冗余编码图片的关联在第 7.4.1.2.5 节中描述。
比特流中的第一个访问单元以比特流的第一个 NAL 单元开始。
在主编码图片的最后一个 VCL NAL 单元之后的以下任何 NAL 单元中的第一个指定新访问单元的开始:
访问单元分隔符 NAL 单元(如果存在),
序列参数集 NAL 单元(如果存在),
图片参数集 NAL 单元(如果存在),
SEI NAL 单元(如果存在),
nal_unit_type 在 14 到 18 范围内的 NAL 单元,包括(如果存在),
主编码图片的第一个 VCL NAL 单元(始终存在)。
第 7.4.1.2.4 节规定了检测主编码图像的第一个 VCL NAL 单元的约束。
访问单元内的编码图片和非 VCL NAL 单元的顺序应遵守以下约束:
当存在访问单元分隔符 NAL 单元时,它应该是第一个 NAL 单元。任何访问单元中最多有一个访问单元分隔符 NAL 单元。
当存在任何 SEI NAL 单元时,它们应位于主编码图像之前。
当存在包含缓冲周期 SEI 消息的 SEI NAL 单元时,缓冲周期 SEI 消息应是访问单元中第一个 SEI NAL 单元的第一个 SEI 消息有效负载。
主编码图片应在相应的冗余编码图片之前。
当存在冗余编码图片时,它们应按照redundant_pic_cnt 值的升序排列。
当存在序列参数集扩展 NAL 单元时,它应是序列参数集 NAL 单元之后的下一个 NAL 单元,该单元具有与序列参数集扩展 NAL 单元中相同的 seq_parameter_set_id 值。
当存在一个或多个没有分区 NAL 单元的辅助编码图片的编码切片时,它们应跟随主编码图片和所有冗余编码图片(如果有)。
当序列结束 NAL 单元出现时,它应跟随主编码图片和所有冗余编码图片(如果有)和辅助编码图片的所有编码切片,而不分割 NAL 单元(如果有)。
当流 NAL 单元结束时,它应是最后一个 NAL 单元。
nal_unit_type 等于 0、12 或在 20 到 31 范围内(含)的 NAL 单元不得位于主编码图片的第一个 VCL NAL 单元之前。
(注 2 – 序列参数集 NAL 单元或图片参数集 NAL 单元可能存在于访问单元中,但不能跟随访问单元内主编码图片的最后一个 VCL NAL 单元,因为此条件将指定一个新的访问单元。)
(注 3 – 当 nal_unit_type 等于 7 或 8 的 NAL 单元存在于访问单元中时,它可能会或可能不会在其存在的访问单元的编码图片中被引用,并且可以在后续访问单元的编码图片。)
不包含nal_unit_type等于0、7、8或12-18(含)或20-31(含)范围内的任何NAL单元的访问单元的结构如图7-1所示。
7.4.1.2.4 检测主编码图像的第一个 VCL NAL 单元
本节规定了对 VCL NAL 单元语法的约束,这些约束足以检测每个主编码图片的第一个 VCL NAL 单元,以检测符合附件 A 中指定的一个或多个配置文件并使用解码器解码的编码视频序列第 2-9 条中规定的过程。
任何编码切片 NAL 单元或编码切片数据分区 A NAL 单元的当前访问单元的主要编码图片应不同于任何编码切片 NAL 单元或编码切片数据分区 A NAL 单元的主要编码图片的先前访问单元通过以下一种或多种方式:
(注 1 – 上述声明的结果是 frame_num 等于 1 的主编码图片不能包含等于 5 的 memory_management_control_operation 除非下面列出的一些其他条件满足它之后的下一个主编码图片(如果有的话) .
pic_parameter_set_id 的值不同。
field_pic_flag 的值不同。
bottom_field_flag 存在于两者中并且值不同。
nal_ref_idc 的值不同,其中一个 nal_ref_idc 值等于 0。
pic_order_cnt_type 对于两者都等于 0,并且 pic_order_cnt_lsb 的值不同,或者 delta_pic_order_cnt_bottom 的值不同。
pic_order_cnt_type 对于两者都等于 1,并且 delta_pic_order_cnt[0] 的值不同,或者 delta_pic_order_cnt[1] 的值不同。
IdrPicFlag 的值不同。
两者的 IdrPicFlag 都等于 1,并且 idr_pic_id 的值不同。
(注 2 – 冗余编码图片中的一些 VCL NAL 单元或一些非 VCL NAL 单元(例如,访问单元分隔符 NAL 单元)也可用于检测访问单元之间的边界,因此可能有助于检测新的主编码图像的开始。)
据我所知,访问单元分隔符不是强制性的。而一个 h.264 流通常在流的开头只包含一个序列参数集。
我认为您不能仅根据最终单元标题信息安全地找到访问单元边界。您将需要解析切片标头中的一些信息。参数 frame_num 标识一张图片,因此是一个访问单元,但为了解析它,您可能需要来自比特流的更多信息。
您可以假设一个访问单元始终只包含一个切片(最终单元类型 1-5)来试试运气,尽管这绝对不符合标准。