6

有没有办法解析 HEVC 比特流文件?

我希望能够创建一个新的比特流文件,其中包含从原始比特流文件中选择的最终单元数据包。

编辑:我插入了我的代码。请在此处找到我的比特流文件。

#library for searching in a string
import re

#library to keep dictionary order
import collections
import bitstring
from bitstring import BitStream, BitArray, ConstBitStream, pack
from bitstring import ByteStore, offsetcopy

#read bitstream file
s = BitStream(filename='11LTCCA_560x416_50Hz_8b_P420_GOP8_IP48_200frms_QP28.HEVC.str')

#find no of packets
pcks = list(s.findall('0x000001', bytealigned=True))

print len(pcks)

#set the current position, in the beginning of the nal unit.
s.pos =pcks[0]-8
print s.pos

#find the number of bits of first nal packet
no_p = pcks[1]-pcks[0]


forbidden_zero_bit = s.read(1)
nal_unit_type = s.read('uint:6')

# go to the beginning of the second nal unit
s.read(no_p)
# print nal unit type of the 1st packet
print nal_unit_type

no_p = pcks[2]-pcks[1]
s.pos = pcks[1]-8
print s.pos
forbidden_zero_bit = s.read(1)
nal_unit_type = s.read('uint:6')
s.read(no_p)
print nal_unit_type
4

2 回答 2

9

如果你要做的只是取一些最终的单元数据包(例如取决于层id和时间id),并且你不需要修改VPS、SPS、PPS、Slice Header等,那么你也可以轻松实现这个你自己:

HEVC 标准的附件 B“字节流格式”中规定了相应的语法。

简而言之:

  1. 在比特流文件中搜索模式 0x000001,它将所有最终单元分开。此外,如果下一个最终单元是访问单元的第一个最终单元(访问单元 = 用于解码整个帧的所有最终单元),则此模式之前可以有一个 0x00 字节。

  2. 根据HEVC 标准的第 7.3.1.2 节读取最终单元标题,并根据您想要的任何标准保留/删除最终单元。确保保留参数集(根据HEVC 标准的表 7-1 的最终单元类型 32、33 和 34 )。

  3. 将所有最终单元组装到一个新文件中,并确保中间始终有 0x000001 序列。

我曾经使用 Python 做过类似的事情,效果很好。如果您想更轻松地阅读最终单元标题,请使用bitstring 模块。如果您想这样做并且有更详细的问题,如果您愿意,可以pm我寻求帮助。

编辑: 关于您发布的代码:为什么在 BitStream 对象(s.pos =pcks[0]-8s.pos = pcks[1]-8)中分配位置时放置“-8”?这应该是 +24(24 位 = 3 字节 = 最终单元分隔符的长度 0x000001),以便在分隔符之后开始读取以获取最终单元。但是,在读取数据时必须考虑到这一点:no_p = pcks[1]-pcks[0]应该是no_p = pcks[1]-pcks[0]-24,因为您在最终单位分隔符之后开始读取。

如果您对第一个找到的位置 ( ) 是 8 而不是 0 感到困惑:根据HEVC 标准pcks[0]的附件 B,在每个最终单元分隔符之前,可以有任意数量的零字节。通常,每个访问单元之前总是有一个零字节。

于 2014-07-28T13:09:42.173 回答
0

你可以试试 GStreamer。他们有一个用于解析 H.265/HEVC 的插件。只是插件还是相当新的,所以我不确定它现在有多稳定。

您可以在此处获得更多详细信息。

于 2014-07-18T19:18:23.307 回答