【问题标题】:Count frames in H.264 bitstream计数 H.264 比特流中的帧数
【发布时间】:2013-11-07 16:39:21
【问题描述】:

如何计算/检测原始 H.264 比特流中的帧(图片)?我知道有 5 种 VCL NALU 类型,但我不知道如何将它们的序列重新识别为访问单元。我想检测一个帧意味着检测一个访问单元作为访问单元

一组在解码顺序上连续的 NAL 单元,包含 正好是一张初级编码图片。除了初级编码 图片,一个访问单元也可能包含一个或多个冗余编码 图片、一张辅助编码图片或其他 NAL 单元 包含编码图片的切片或切片数据分区。这 访问单元的解码总是会产生解码的图片。

我想让它知道直播到服务器的 FPS 是多少。

【问题讨论】:

    标签: ffmpeg video-streaming h.264 video-encoding


    【解决方案1】:

    你的解释是对的,如果你想自己解析流,看here

    但是要以易于阅读和解析的格式(使用任何文本解析器)快速提取流信息,您可以使用ffprobe

    ffprobe -show_streams -count_frames -pretty filename
    

    你会在输出中找到:

    • nb_read_frames=....

    对于 fps,我听说 ffprobe 可能会报告一些 fps 错误,尝试一个简单的ffmpeg -i 命令。

    ffmpeg -i filename 2>&1 | sed -n "s/.*, \(.*\) fps.*/\1/p"
    

    【讨论】:

    • ffmpeg -i filename 将向您显示预期的 FPS,但不会计算可变帧率视频流的真实帧率。 ffprobe -count_frames 是我发现明确计算帧数的唯一方法(注意,这很慢,因为它必须读取整个文件!)。将其输出除以视频中的秒数以获得真正的 FPS。另请参阅我的 media-scripts 套件中的 framerate 脚本。
    【解决方案2】:

    来自 ITU-T H.264 (03/2009):

    7.4.1.2.3 NAL 单元和编码图片的顺序以及与访问单元的关联

    本小节规定了 NAL 单元和编码图片的顺序以及与使用第 2-9 节中规定的解码过程解码的符合附件 A 中指定的一个或多个配置文件的编码视频序列的访问单元的关联。

    一个访问单元由一个主编码图片、零个或多个相应的冗余编码图片和零个或多个非 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 单元的约束。

    7.4.1.2.4 检测主编码图片的第一个VCL NAL单元

    本子条款规定了对 VCL NAL 单元语法的约束,这些约束足以检测每个主编码图片的第一个 VCL NAL 单元,以检测符合附件 A 中指定的一个或多个已解码配置文件的编码视频序列使用第 2-9 节中指定的解码过程。

    当前访问单元的主要编码图片的任何编码切片 NAL 单元或编码切片数据分区 A NAL 单元应不同于当前访问单元的主要编码图片的任何编码切片 NAL 单元或编码切片数据分区 A NAL 单元通过以下一种或多种方式访问​​单元:

    • frame_num 的值不同。用于测试此条件的 frame_num 的值是出现在 slice header 的语法中的 frame_num 的值,无论该值是否被推断为等于 0 以供后续在解码过程中使用,因为 memory_management_control_operation 的存在等于 5。(注 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 单元)也可用于检测访问单元之间的边界,并且可能因此有助于检测新的主编码图片的开始。)

    【讨论】:

      【解决方案3】:

      NAL 单元与帧不一定具有 1-1 关系。帧可以分成多个 NAL 单元。如果要手动解析流,则需要处理下面博客文章中定义的每种类型。如果流有一个 SPS NAL 数据包,它应该包含帧速率,但这不一定是实际的帧速率,只是容器认为它具有的。

      正如您还询问如何找到 AU 的实际开始,如果它是“附件 B”比特流,则每个 NALU 将有一个开始代码 0x000001 或 0x00000001。 AVCC 使用一个小的 header 来定义 NALU 的长度。

      查看以下精彩博文了解更多详情:szatmary.org

      希望有帮助!

      【讨论】:

      • 是否有您正在寻找的其他具体细节?
      猜你喜欢
      • 2015-12-12
      • 1970-01-01
      • 2011-08-18
      • 1970-01-01
      • 1970-01-01
      • 2014-05-06
      • 1970-01-01
      • 1970-01-01
      • 2019-07-18
      相关资源
      最近更新 更多