; $Id: //depot/idl/IDL_70/idldir/examples/doc/objects/mj2_timer_doc.pro#1 $ ; Copyright (c) 2005-2007, ITT Visual Information Solutions. All ; rights reserved. ; ;+ ; FILE: ; mj2_timer_doc.pro ; ; CALLING SEQUENCE: mj2_timer_doc ; ; PURPOSE: ; Demonstrates how to use a widget timer event to control ; the display rate of a Motion JPEG2000 file that has ; frames with varying frame lengths. ; ; ; MAJOR TOPICS: Language ; ; EXTERNAL FUNCTIONS, PROCEDURES, and FILES: ; none. ; ; NAMED STRUCTURES: ; none. ; ; COMMON BLOCS: ; none. ; ; MODIFICATION HISTORY: ; 11/05, SM - written ;- ;----------------------------------------------------------------- ; PRO mj2_timer_doc_event, sEvent ; ; General widget event where WIDGET_TIMER events are accessed - ; used to control playback rate of frames (vFrameRate). This is ; computed from the FRAME_RATE and TIMESCALE properties of the ; IDLffMJPEG2000 object. COMPILE_OPT IDL2, HIDDEN ; Get the number of frames and the current frame number. WIDGET_CONTROL, sEvent.top, GET_UVALUE=pState (*pState).oMJ2->GetProperty, N_Frames=nFrames, TIMESCALE=vTimeScale ; If the widget had more than one event, the following line would ; find timer events. IF (TAG_NAMES(sEvent, /STRUCTURE_NAME) EQ 'WIDGET_TIMER') THEN BEGIN ; Play all available frames (nFrames). Return the frame period of ; each frame to compute the playback rate. frameIndex = (*pstate).oMJ2->GetSequentialData(Data, $ FRAME_PERIOD = vFramePeriod) vFrameRate = FLOAT(vFramePeriod)/FLOAT(vTimeScale) ; If request for data is too fast, handle return of -1. Repeat ; request until return value is not -1 and then repeat previous ; steps to access frame period and compute frame rate. If frameIndex EQ -1 THEN BEGIN REPEAT BEGIN ; Get the next frame from the frame buffer. frameIndex = (*pState).oMJ2->GetSequentialData(Data, $ FRAME_PERIOD = vFramePeriod) vFrameRate = FLOAT((vFramePeriod)/vTimeScale) ENDREP UNTIL (frameIndex NE -1) ENDIF ELSE BEGIN ; If a frame is available, display it. TV, Data ; Release the frame and make buffer slot available. (*pState).oMJ2->ReleaseSequentialData, frameIndex ; Figure frames per second for display in label on widget. vFramePerSec = STRING(1/(vFrameRate)) strFrameRate = "Frame rate:" + vFramePerSec + " frames/s" ; Update timer with current frame rate. WIDGET_CONTROL, (*pState).wBase, Timer=vFrameRate WIDGET_CONTROL, (*pState).wLabel, SET_VALUE=strFrameRate ENDELSE ENDIF WIDGET_CONTROL, sEvent.TOP, SET_UVALUE=pState END ;----------------------------------------------------------------- ; PRO mj2_timer_doc_cleanup, id ; ; Release the frames from the frame buffer and ; shut down the background processing thread. ; Clean up object and pointer. WIDGET_CONTROL, id, GET_UVALUE=pState Status = (*pState).oMJ2->StopSequentialReading() OBJ_DESTROY, (*pState).oMJ2 PTR_FREE, pState END ;----------------------------------------------------------------- ; PRO mj2_timer_doc ; ; Create a MJ2 file containing frames with varying frame period values. ; These values will be passed to the widget timer to control how ; frequently timer events are fired. Therefore, the playback rate ; reflects the rate set for each frame. ; Read image data, which contains 57 frames. nFrames = 57 head = READ_BINARY( FILEPATH('head.dat', $ SUBDIRECTORY=['examples','data']), $ DATA_DIMS=[80,100, 57]) ; Create new MJ2 file in the temporary directory. file = FILEPATH("mj2_timer_ex.mj2", /TMP) ; Create an IDLffMJPEG2000 object. oMJ2write=OBJ_NEW('IDLffMJPEG2000', file, /WRITE, /REVERSIBLE) ; Write the data of each frame into the MJ2 file. ; Set playback characteristics of the frames based on index value. ; An increase in vFramePeriod value slows playback when ; the TIMESCALE property is constant. FOR i=0, nFrames-1 DO BEGIN If (i GE 0) AND (i LE 18) THEN vFramePeriod=1500 IF (i GE 19) AND (i LE 37) THEN vFramePeriod=4000 IF (i GE 38) AND (i LE 57) THEN vFramePeriod=10000 data = CONGRID(head[*,*,i], 240, 300, /INTERP) result = oMJ2write->SetData(data, FRAME_PERIOD=vFramePeriod) ENDFOR ; Commit and close the IDLffMJPEG2000 object. return = oMJ2write->Commit(100000) OBJ_DESTROY, oMJ2write ; Create a new IDLffMJPEG2000 object to access MJ2 file. oMJ2=OBJ_NEW("IDLffMJPEG2000", file) oMJ2->GetProperty,N_FRAMES=nFrames, DIMENSIONS=dims, $ FRAME_PERIOD=vFramePeriod, TIMESCALE=vTimeScale ; Figure frames per second for display in label on widget. vFrameRate = FLOAT(vFramePeriod)/vTimeScale vFramePerSec = STRING(1/(vFrameRate)) ; Create base and draw widgets. wBase = WIDGET_BASE(/COLUMN, TITLE="Simple MJ2 Playback", $ KILL_NOTIFY='mj2_timer_doc_cleanup', UVALUE='TIMER') wDraw = WIDGET_DRAW(wBase, xsize =240, ysize=300) strFrameRate = "Frame rate:" + vFramePerSec + " frames/s" wLabel = WIDGET_LABEL(wBase, VALUE=strFrameRate) ; Realize base and initialize timer. WIDGET_CONTROL,/REALIZE, wBase WIDGET_CONTROL, wBase, TIMER=vFrameRate ; Start reading the frames into the frame buffer in a ; background processing thread. Status = oMJ2->StartSequentialReading() ; Create state structure. state = {oMJ2:oMJ2, wBase:wBase, wLabel:wLabel} pState = PTR_NEW(state) WIDGET_CONTROL, wBase, set_UVALUE=pstate XMANAGER, 'mj2_timer_doc', wBase, /NO_BLOCK END