×
[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歳のハローワールド
カレンダー
06 | 2025/07 | 08 |
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 | 31 |
最新記事
(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]
最新トラックバック
カテゴリー
アーカイブ
ブログ内検索
アクセス解析