再配布 > ページ境界処理テスト用

ページ境界処理テスト用プラグイン


  • 技術的な話
876 :名無しさん@お腹いっぱい。:2008/07/01(火) 05:46:53 ID:rU3tuL6Q0
    今気がついたんだが、99d3になってまた(まだ?)rgb2yc()の処理がおかしい気がするな。
    pixelpに投げたポインタから少なくとも8バイト分は一気に読みに行くようで
    確保したメモリ領域が8バイトの倍数でないと、確保されていないところまで読みに行って
    0xc00000005の例外が出る。オフセットアドレスは0x00037e1aだそうだ。
    てっきり作りかけの自作プラグインが悪いのかと思っちまった・・・

877 :名無しさん@お腹いっぱい。:2008/07/01(火) 06:14:37 ID:rU3tuL6Q0
    ごめん、分かりにくいかもしれないので補足。
    検証のためにやったことは、
    1. バッファの末尾(BMP的には先頭)の1ラインを一気に処理→画像によってOKだったりNGだったり
    2. 1.でNGな画像のバッファの中間の1ラインを一気に処理→OK
    3. 1.でNGな画像のバッファの末尾のラインの左端1ピクセル目だけ処理→OK
    ・・・(中略)・・・
    4. 1.でNGな画像のバッファの末尾のラインの右端から3ピクセル目だけを処理→OK
    5. 1.でNGな画像のバッファの末尾のラインの右端から2ピクセル目だけを処理→NG

    24bit BMPを扱っているので、右端から3ピクセル目だと
    確保されているバッファは残り9バイトだが
    2ピクセル目では残り6バイトになる。

    あれ、よく考えたら>>876説では1.でNGになった画像が横512ピクセルなのと矛盾するな。
    徹夜で頭がボケてら・・・
    ちなみに横が4096ピクセルとか848ピクセルとか378ピクセルとか22ピクセルのは大丈夫だった。

878 :名無しさん@お腹いっぱい。:2008/07/01(火) 06:20:36 ID:z1borOEQ0
    >>877
    そのバッファはどうやって確保してる?

    メモリは4KBのページ単位で確保されているので、
    うまい具合にバッファの末尾がページの最終バイトになるようにしないと、
    ちゃんと再現しないよ?

879 :名無しさん@お腹いっぱい。:2008/07/01(火) 06:22:53 ID:z1borOEQ0
    まさかとは思うけど、
    BMPは1ラインが4バイトの倍数になるようにパディングが必要
    ってことを忘れていて、あなたが確保したメモリが足りない・・・だったりする?

880 :名無しさん@お腹いっぱい。:2008/07/01(火) 06:24:48 ID:r2l78CL70
    >>824
    マジできてる━━━━(Д゚(○=(゚∀゚)=○)Д゚)━━━━!!!!
    プラグインの作者様達乙なのです。

881 :名無しさん@お腹いっぱい。:2008/07/01(火) 06:28:47 ID:z1borOEQ0
    ごめん、自分も眠くてボケてた。

    >>878と>>879は、なかったことにして。

882 :名無しさん@お腹いっぱい。:2008/07/01(火) 06:31:01 ID:rU3tuL6Q0
    >>878-879
    朝早くからレスありがとう。
    バッファは原始的にmalloc()してる。
    ただ、rgb2yc()は元のデータがBMPだったかどうかは全然関係ないわけで、
    BMPの読み込みが正常に完了してる以上はメモリが足りないことはないと思うんだな。
    もうちょっと追試してみたが横じゃなくて縦も関係あるようだ・・・

    512x47→OK
    512x48→NG

    いったい何が悪いんだ・・・orz

883 :名無しさん@お腹いっぱい。:2008/07/01(火) 06:35:18 ID:z1borOEQ0
    >>882
    NGなのは確実にNGとしても、
    OKなのは、偶然そのアドレスが有効だったので、たまたま動いているだけ、だと思う。


884 :名無しさん@お腹いっぱい。:2008/07/01(火) 06:36:42 ID:rU3tuL6Q0
    ポインタをよーく観察したら、やっぱりページ境界が関わっているようだ。
    バッファの先頭がページの先頭になるとして、
    512x47の画像を読み込んだ時にはバッファの末尾がページ境界に来ないが、
    512x48の画像だとバッファの末尾がちょうどページ境界になる。

885 :名無しさん@お腹いっぱい。:2008/07/01(火) 06:39:39 ID:rU3tuL6Q0
    書き込むとレスが付いてる法則・・・

    >>883
    自分もそういう結論に達した。
    やっぱり原因はrgb2yc()の中にあるようだ。とりあえず修正されるまでの間は
    バッファがページ境界ぴったりに収まってしまう場合もう1ページ余分に確保するしかないか・・・

886 :名無しさん@お腹いっぱい。:2008/07/01(火) 06:41:46 ID:z1borOEQ0
    あーうまく1レスにまとめて書けなくて連投でゴメン

    OKなのは、本当にOKなのと、たまたま動いているだけの2つ。

    たまたま動いているのがNGになるようにするためには、
    Win32APIのVirtualAllocを使って、
    1バイトでもオーバーランしたらページアクセス違反になるようにする。

    具体的には、
    VirtualAllocにMEM_RESERVEを付けてアドレス空間を予約する
    VirtualAllocにMEM_COMMITを付けてメモリを確保する
    メモリを確保している範囲と予約しただけの範囲の境目が、
    バッファの終わりになるようにRGBデータをメモリに書き込み、
    rgb2ycを呼び出す。

887 :名無しさん@お腹いっぱい。:2008/07/01(火) 07:21:57 ID:rU3tuL6Q0
    >>886
    それの確実なやり方なんだけど、1回目ではわざと大きめに予約しておいて、
    2回目で1回目に返ってきたアドレスをぶち込んでサイズは画像ぴったりに確保、でおk?

    一応上のやり方で確保してテストしてみた。
    だけど・・・不思議なことに挙動に変化はなかった。
    そして予想通り、確保する領域を1ページだけ増やしたら動いた。

888 :名無しさん@お腹いっぱい。:2008/07/01(火) 07:44:10 ID:z1borOEQ0
    >>887
    2回目のときのサイズは画像ピッタリでOK (OS側がページサイズに切り上げてくれる)
    ただし、画像の末尾がページ境界になるように、画像を配置する。

    たとえば画像が100バイトだとしたら、
    100バイト+4Kバイトを予約 → 8Kバイトが予約される
    そのアドレスで100バイトをコミット → 4Kバイトがコミットされる

    そのアドレスから、4096 - (100 % 4096) バイト 進んだ位置に、
    画像100バイトの画像をコピー。その100バイトの先頭をrgb2ycに渡す

    こんな感じです。

889 :名無しさん@お腹いっぱい。:2008/07/01(火) 08:05:22 ID:rU3tuL6Q0
    >>888
    おk
    再現できた。
    アクセス違反の起こったアドレスはすべて4kページ境界。

890 :名無しさん@お腹いっぱい。:2008/07/01(火) 08:28:24 ID:z1borOEQ0
    乙

    あとは作者に連絡するだけですね。

891 :名無しさん@お腹いっぱい。:2008/07/01(火) 08:44:05 ID:y/RFWf640
    >>876-890
    おまいらそれ何語でしか?

892 :名無しさん@お腹いっぱい。:2008/07/01(火) 09:00:55 ID:rU3tuL6Q0
    >>890
    朝っぱらから検証手伝ってくれて㌧
    今はメールしか連絡手段ないのか・・・

893 :名無しさん@お腹いっぱい。:2008/07/01(火) 09:01:53 ID:WodilLXp0
    サルでもわかるように説明していただけるとありがたい
    99d3地雷?

895 :名無しさん@お腹いっぱい。:2008/07/01(火) 09:35:32 ID:rU3tuL6Q0
    >>893
    サルが分かるかは自信がないが・・・

    どのバージョンからそうなったかについては調べていないが、
    AviUtlに用意されている rgb2yc() という関数を使ってRGBとYCrCbの変換をしている
    プラグインは、作業用メモリの確保のやり方次第で地雷を踏む可能性があることが分かった。
    ひょっとすると同じことが逆変換の yc2rgb() にも言える可能性がある(これも要調査)。
    ただ、謹製のテロップフィルタは地雷ではなかった。

    標準の構成のまま使うならおそらく問題はないだろう。
    BMP画像を扱う外部のプラグインは地雷を踏む可能性が比較的高いので要注意。

    ちなみに、地雷を踏んでも例外のダイアログで「はい」を選べばそこから安全に終了できる。

896 :名無しさん@お腹いっぱい。:2008/07/01(火) 10:13:56 ID:SCJUP7yc0
    d3は別に地雷ってわけじゃないよ。
    ただプラグイン使うと例外エラー起きちゃうことがあってそれがとにかく腹が立つだけさ。
    プラグイン使わないなら特にきにしなくていいんじゃないかな。
    俺もよくは知らないけど。

897 :名無しさん@お腹いっぱい。:2008/07/01(火) 10:27:55 ID:KlMp66tr0
    プラグイン作成するときはメモリを少し余分に確保しておけってことかな?
    他のソフトもそうだけど、バグは絶対あるものと思って保険かけとけと。

898 :名無しさん@お腹いっぱい。:2008/07/01(火) 10:28:58 ID:DVkFJgPM0
    なんだ、要するに今日は快晴ってことか・・・

899 :名無しさん@お腹いっぱい。:2008/07/01(火) 10:43:50 ID:WodilLXp0
    >>895-896
    なんとなく漏れは大丈夫そうかな?
    解説㌧
    d4だか99eだかわからんが早く直してくれるといいな

900 :名無しさん@お腹いっぱい。:2008/07/01(火) 11:49:33 ID:/EXYkM9/0
    なんだシークさせてくとエラーだすのはSSE2のせいかとおもってたぜ 

911 :876:2008/07/01(火) 18:22:33 ID:rU3tuL6Q0
    例の件、実感湧かない人も多いんじゃないかと思うので
    テスト用のプラグインフィルタを作ってみた。

    ttp://www2.uploda.org/uporg1517234.zip.html
    DLパスは名前

    ちなみに手元のテストでは99a3まで全部再現した。
    従って99d2での修正は関係ない模様。 




名前:
コメント:

タグ:

+ タグ編集
  • タグ:

このサイトはreCAPTCHAによって保護されており、Googleの プライバシーポリシー利用規約 が適用されます。

最終更新:2008年07月02日 14:41
ツールボックス

下から選んでください:

新しいページを作成する
ヘルプ / FAQ もご覧ください。
添付ファイル