解析多组视频帧的原始二进制文件

时间:2015-10-15 16:18:26

标签: python parsing multiplexing

我正在尝试使用已知的标头和长度解析Python中的原始二进制文件。

数据是6通道多路复用视频。

该文件遵循以下规则来分隔帧:

  • 字节1:表示通道#(例如0xE0,0xE1,0xE2 ......)
  • 字节4& 5:表示图像数据的长度
  • 字节6:长度:图像数据
  • 图像数据的末尾用0xFF填充,这样每个图像块都以16字节行的第一个字节开始。

图像数据的开头

E0 01 00 00 D2 59 80 C1 27 3F EC BB 31 7B 3F EC 

BB 31 7B 0F 9B 90 5D A8 81 AA 5F A9 C1 D2 4B B9

9D 0A 8D 1B 8F 89 44 FF 4E 86 92 AD 00 90 5B A8

图像数据结束

67 49 0B B5 BC 82 38 AE 5E 46 49 86 6A FF 24 97 

69 8C 6F 17 6D 67 B5 11 C7 E5 FB E3 3F 65 1F 22 

5C F3 7C D0 7C 49 2F CD 26 37 4D 40 FF FF FF FF

源文件大几GB。将每个频道解析为单独文件的最佳方法是什么?另外,如何一次批量处理多个文件,根据输入名称保存文件?

1 个答案:

答案 0 :(得分:0)

解析很小的多GB二进制文件块可能不是Python会非常快的,因为它需要大量的函数调用和对象创建,这意味着大量的RAM和CPU开销。如果您需要更高的性能或对内存管理的控制,最好以较低级别的语言(C,C ++,Go,Rust)执行此操作。

但是,您可以使用struct模块在​​Python中执行此类操作,如下所示:

header = struct.Struct('>BBBH')
data = b'\xE0\x01\x00\x00\xD2\x59\x80...'  # read this from input file
view = memoryview(data)
offset = 0
while offset < len(data):
    channel, _, _, length = header.unpack(view[offset:offset + header.size])
    write_output(channel, view[header.size:header.size + length])
    offset += length

注意事项:

  • 确定长度是大端还是小端(格式字符串中为< vs >
  • 使用memoryview是一种避免一些额外对象复制和创建的方法 - 希望它能提高效率
  • 您希望保持输出文件处于打开状态 - 我只是将其隐藏在write_output()以上
  • 如果输入为多GB,您可能希望以1MB的块或合理的方式读取输入文件,而不是一次性读取
  • 注意字节与字符串(Python 2.x与3.x的不同处理方式)
  • 如果您需要了解有关打开,阅读和撰写文件的更多信息,请随时发布更具体的问题

对于一次批量处理多个文件,最好的选择是multiprocessing模块。需要一段时间才能解决问题,但在此之后使用起来非常简单。