我正在尝试将YCbCr 文件 从 8 bpp 转换为 10 bpp。
到目前为止,我最好的方法仍然比最基本的幼稚 C 实现慢一个数量级。
C 中的幼稚方法,运行时间约为 8 秒。使代码改为在块上工作,将时间降低到 1 秒以下。
我很好奇从标准 python 处理二进制文件可以获得什么样的性能。示例文件采用CIF 分辨率,与 1080p 的内容相比“小”。尽管我主要对标准 python 感兴趣,但也可以随意添加 numpy-suggestions。
测试文件可以从
http://trace.eas.asu.edu/yuv/foreman/foreman_cif.7z
sha1sum
对于正确的 10 位输出是
c511dabc793383f7fd0ed69b4bb9b9f89ef73b84
Python:
#!/usr/bin/env python
import array
f_in = 'foreman_cif.yuv'
f_out = 'py_10bpp.yuv'
def bytesfromfile(f):
while True:
raw = array.array('B')
raw.fromstring(f.read(8192))
if not raw:
break
yield raw
with open(f_in, 'rb') as fd_in, \
open(f_out, 'wb') as fd_out:
for byte in bytesfromfile(fd_in):
data = []
for i in byte:
i <<= 2
data.append(i & 0xff)
data.append((i >> 8) & 0xff)
fd_out.write(array.array('B', data).tostring())
天真的C-dito:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char** argv)
{
int c;
int d[2];
FILE* fd_in;
FILE* fd_out;
fd_in = fopen("foreman_cif.yuv", "rb");
fd_out = fopen("c_10bpp.yuv", "wb");
while((c = fgetc(fd_in)) != EOF) {
c <<= 2;
d[0] = c & 0xff;
d[1] = (c >> 8) & 0xff;
fwrite(&d[0], 1, 1, fd_out);
fwrite(&d[1], 1, 1, fd_out);
}
fclose(fd_in);
fclose(fd_out);
return EXIT_SUCCESS;
}