×
[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。
// Encode 8x8 macroblocks
var DCY:Number=0;
var DCU:Number=0;
var DCV:Number=0;
bytenew=0;
bytepos=7;
for (var ypos:int=0; ypos<image.height; ypos+=8) {
for (var xpos:int=0; xpos<image.width; xpos+=8) {
RGB2YUV(image, xpos, ypos);
DCY = processDU(YDU, fdtbl_Y, DCY, YDC_HT, YAC_HT);
DCU = processDU(UDU, fdtbl_UV, DCU, UVDC_HT, UVAC_HT);
DCV = processDU(VDU, fdtbl_UV, DCV, UVDC_HT, UVAC_HT);
}
}
この部分がどうやらencode()で一番時間を喰っているらし。全画素を8x8のブロックに分割して、まあ離散フーリエか何かの変換処理をしているらしい。なので、この処理をencode()から追い出して、タイマイベント内でループさせることにしました。まずあ、新しいエンコーダクラスにはIEventDispatcherを実装させます。一定回数ループを回したら、一旦タイマイベントを終了させてProgressEventをDispatchさせるようにしたいと思います。 まず上のforループの代わりにencodeは変数を初期化、タイマーを起動して自身は終了させます。
_progress=0; _pw = int(_image.width +7) >>> 3 ; //x方向のブロック数 _ph = int(_image.height +7) >>> 3 ; //y方向の同 _total=_pw * _ph; //8x8のブロックがいくつあるか _period = 1 << int(Math.log(_total) / Math.LN2); //_totalを超えない最大の2の冪乗を求め _period = _period > 0xff ? ( _period >>> 8) - 1 : 0; //256で割って1引く → 2進表現で全て1に //ここでタイマーを開始する timer.addEventListener(TimerEvent.TIMER, timerHandler); timer.start();_periodは進捗イベントの条件式に使用する値で、条件文をビット演算で行うために(ループ毎に実行されるため)上記のような妙な値を入れています。 次にタイマイベント。
// Encode 8x8 macroblocks
private function timerHandler(e:TimerEvent):void{
var ypos:int = int(_progress / _pw) << 3;
var xpos:int = (_progress % _pw) << 3;
while (true) {
RGB2YUV(_image, xpos, ypos);
_DCY = processDU(YDU, fdtbl_Y, _DCY, YDC_HT, YAC_HT);
_DCU = processDU(UDU, fdtbl_UV, _DCU, UVDC_HT, UVAC_HT);
_DCV = processDU(VDU, fdtbl_UV, _DCV, UVDC_HT, UVAC_HT);
_progress++;
//x位置移動
xpos = int(_progress % _pw) << 3;
//xが一周したらy位置移動
if (xpos==0) ypos = int(_progress / _pw) <<3;
//最後までいったら
if(_progress == _total){
//タイマーを停止させて
timer.stop();
timer.removeEventListener(TimerEvent.TIMER, timerHandler);
//completeイベント送って
dispatcher.dispatchEvent(new Event(Event.COMPLETE));
// Do the bit alignment of the EOI marker
if ( bytepos >= 0 ) {
var fillbits:BitString = new BitString();
fillbits.len = bytepos+1;
fillbits.val = (1<<(bytepos+1))-1;
writeBits(fillbits);
}
writeWord(0xFFD9); //EOI
break;
} else if ( (_progress & _period) == 0) { //一定の回数ループさせたら
//progressイベントを送って
dispatcher.dispatchEvent(
new ProgressEvent(
ProgressEvent.PROGRESS, false, false, _progress, _total
));
//次回のタイマーイベントに続く
break;
}
}
}
こんな感じで、めでたく進捗を取得出来るようになりました。encode()自体はByteArrayを返さなくなるので、呼び出し側のクラス内でコンプリートイベントのメソッド内でByteArrayを取得する必要があります。なのでゲッタも追加しました。
//コンプリートを確認したらゲッタからbyteArrayを取得する
public function get byteArray():ByteArray {
return byteout;
}PR
この記事にコメントする
26歳のハローワールド
カレンダー
| 10 | 2025/11 | 12 |
| S | M | T | W | T | F | S |
|---|---|---|---|---|---|---|
| 1 | ||||||
| 2 | 3 | 4 | 5 | 6 | 7 | 8 |
| 9 | 10 | 11 | 12 | 13 | 14 | 15 |
| 16 | 17 | 18 | 19 | 20 | 21 | 22 |
| 23 | 24 | 25 | 26 | 27 | 28 | 29 |
| 30 |
最新記事
(05/23)
(05/11)
(05/09)
(05/08)
(05/08)
(03/07)
(02/25)
(02/07)
(02/07)
(01/28)
最新コメント
[11/27 gyzwviyehl]
[11/18 Tepexaxyonelo]
[09/12 gomFolley]
[08/16 CypeBachCoece]
[06/02 gb]
[03/06 kishima]
[01/18 KNDY]
[01/16 kage]
[12/23 KNDY]
[12/23 kage]
最新トラックバック
カテゴリー
アーカイブ
ブログ内検索
アクセス解析