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
パイソン:
#!/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-ディト:
#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;
}