'From Squeak2.9alpha of 13 June 2000 [latest update: #2518] on 21 November 2000 at 1:23:13 pm'! "Change Set: MPEGPlayerJMM Date: 19 Nov 2000 Author: johnmci@smalltalkconsulting.com This is an MPEG player interface (video/audio) It interfaces to a plugin MPEG library and provides a interface to that library. It's used inconjunction with your favorite Morphic MPEG player"! Object subclass: #MPEGFile instanceVariableNames: 'pathToFile fileBits fileIndex endianness ' classVariableNames: 'Registry ' poolDictionaries: '' category: 'MPEG3-Kernel'! !MPEGFile commentStamp: 'JMM 11/8/2000 09:42' prior: 0! * An interface to LibMPEG3 * Author: Adam Williams * Page: heroine.linuxbox.com * * Changed for Squeak to work with Squeak and to work on the Macintosh * Sept 2000, by John M McIntosh johnmci@smalltalkconsulting.com * The smalltalk code and the C code it produces is released under the * Squeak licence. The libmpeg3 C code is co-licenced under either the Squeak licence or * the GNU LGPL ! MPEGFile class instanceVariableNames: ''! SketchMorph subclass: #MPEGImageMorph instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'MPEG3-Kernel'! Smalltalk renameClassNamed: #MpegPlayer as: #MPEGPlayer! Object subclass: #MPEGPlayer instanceVariableNames: 'external form startTime clockBias frameRate lastDelay noSound sampleRate audioPlayerProcess videoPlayerProcess playerProcessPriority soundQueue timeCheck semaphoreForSound errorForSoundStart morph volume ' classVariableNames: '' poolDictionaries: '' category: 'MPEG3-Kernel'! !MPEGPlayer commentStamp: 'JMM 11/8/2000 10:58' prior: 0! V1.01 johnmci@smalltalkconsulting.com Nov 8th 2000 A Simple MPEG Player for playing MPEG3 audio or video | foo | foo _ MpegPlayer playFile: 'my.mpg'. foo playStream: 0. "To play both audio and video, stream #0 " foo playAudioStream: 0 "To play audio stream". foo playVideoStream: 0 "To play video stream" foo playStreamWaitTilDone: 0 "To play audio/video as currrent process" or | foo | foo _ MPEGPlayer playFile: 'my.mpg' onForm: Display. foo playStream: 0. To play full screen. ! MPEGPlayer class instanceVariableNames: ''! TestInterpreterPlugin subclass: #Mpeg3Plugin instanceVariableNames: 'maximumNumberOfFilesToWatch mpegFiles ' classVariableNames: '' poolDictionaries: '' category: 'VMConstruction-Plugins'! !Mpeg3Plugin commentStamp: 'JMM 11/8/2000 09:42' prior: 0! /******************************************************** * An interface to LibMPEG3 * Author: Adam Williams * Page: heroine.linuxbox.com * * Changed for Squeak to work with Squeak and to work on the Macintosh * Sept 2000, by John M McIntosh johnmci@smalltalkconsulting.com * The smalltalk code and the C code it produces is released under the * Squeak licence. The libmpeg3 C code is co-licenced under either the Squeak licence or * the GNU LGPL! Mpeg3Plugin class instanceVariableNames: ''! !MPEGFile methodsFor: 'access' stamp: 'JMM 11/10/2000 00:26'! endianness ^endianness isNil ifTrue: [endianness _ Smalltalk endianness] ifFalse: [endianness]! ! !MPEGFile methodsFor: 'access' stamp: 'JMM 9/20/2000 19:04'! fileHandle (Smalltalk externalObjects at: fileIndex ifAbsent: [^nil]) == fileBits ifTrue: [^fileBits] ifFalse: [^nil]. ! ! !MPEGFile methodsFor: 'access' stamp: 'JMM 9/18/2000 18:38'! fileName ^pathToFile! ! !MPEGFile methodsFor: 'access' stamp: 'JMM 9/20/2000 01:54'! getPercentage "Return current location by percentage, 0.0-1.0" ^self primGetPercentage: self fileHandle ! ! !MPEGFile methodsFor: 'access' stamp: 'JMM 9/29/2000 19:28'! getTOC: timecode doStreams: streams | buffer | buffer _ String new: 64*1024+1. self primGenerateToc: self fileHandle useSearch: timecode doStreams: streams buffer: buffer. ^buffer! ! !MPEGFile methodsFor: 'access' stamp: 'JMM 9/20/2000 01:56'! getTimeCode "Return time code, (float) " ^self primGetTime: self fileHandle! ! !MPEGFile methodsFor: 'access' stamp: 'JMM 9/20/2000 01:53'! seekPercentage: aFloat self primSeekPercentage: self fileHandle percentage: aFloat asFloat ! ! !MPEGFile methodsFor: 'access' stamp: 'JMM 9/20/2000 01:56'! setMMX: aValue " true is set, false is off. May not be supported " self primSetMMX: self fileHandle useMMX: aValue ! ! !MPEGFile methodsFor: 'audio' stamp: 'JMM 11/21/2000 13:12'! audioChannels: aStream "Returns -1 if error, otherwise returns audioChannels for stream aStream" self hasAudio ifFalse: [^-1]. ^[self primAudioChannels: self fileHandle stream: aStream] on: Error do: [-1] ! ! !MPEGFile methodsFor: 'audio' stamp: 'JMM 11/21/2000 13:13'! audioGetSample: aStream "Returns number of current sample, or -1 if error" self hasAudio ifFalse: [^-1]. ^[(self primGetSample: self fileHandle stream: aStream) asInteger] on: Error do: [-1] ! ! !MPEGFile methodsFor: 'audio' stamp: 'JMM 11/21/2000 13:13'! audioReReadBuffer: aBuffer stream: aStreamNumber channel: aChannelNumber "Used to read other channels after first ReadBuffer Returns -1 if error, otherwise 0" self hasAudio ifFalse: [^-1]. ^[self audioReReadBuffer: aBuffer stream: aStreamNumber channel: aChannelNumber samples: (aBuffer size * aBuffer bytesPerElement // 2)] on: Error do: [-1]! ! !MPEGFile methodsFor: 'audio' stamp: 'JMM 11/21/2000 13:13'! audioReReadBuffer: aBuffer stream: aStreamNumber channel: aChannelNumber samples: aSampleNumber "Used to read other channels after first ReadBuffer Returns -1 if error, otherwise 0 Note this call requires passing in the samples to read, ensure you get the number right" self hasAudio ifFalse: [^-1]. ^[self primAudioReReadBuffer: self fileHandle buffer: aBuffer channel: aChannelNumber samples: aSampleNumber stream: aStreamNumber] on: Error do: [-1]! ! !MPEGFile methodsFor: 'audio' stamp: 'JMM 11/21/2000 13:13'! audioReadBuffer: aBuffer stream: aStreamNumber channel: aChannelNumber "Returns -1 if error, otherwise 0" self hasAudio ifFalse: [^-1]. ^[self audioReadBuffer: aBuffer stream: aStreamNumber channel: aChannelNumber samples: (aBuffer size* aBuffer bytesPerElement)//2] on: Error do: [-1]! ! !MPEGFile methodsFor: 'audio' stamp: 'JMM 11/21/2000 13:13'! audioReadBuffer: aBuffer stream: aStreamNumber channel: aChannelNumber samples: aSampleNumber "Returns -1 if error, otherwise 0 Note this call requires passing in the samples to read, ensure you get the number right" self hasAudio ifFalse: [^-1]. ^[self primAudioReadBuffer: self fileHandle buffer: aBuffer channel: aChannelNumber samples: aSampleNumber stream: aStreamNumber] on: Error do: [-1]! ! !MPEGFile methodsFor: 'audio' stamp: 'JMM 11/21/2000 13:13'! audioSampleRate: aStream "Returns sample rate, or -1 if error" self hasAudio ifFalse: [^-1]. ^[self primSampleRate: self fileHandle stream: aStream] on: Error do: [-1] ! ! !MPEGFile methodsFor: 'audio' stamp: 'JMM 11/21/2000 13:13'! audioSamples: aStream "Returns -1 if error, otherwise returns audioSamples for stream aStream" self hasAudio ifFalse: [^-1]. ^[(self primAudioSamples: self fileHandle stream: aStream) asInteger] on: Error do: [-1] ! ! !MPEGFile methodsFor: 'audio' stamp: 'JMM 11/21/2000 13:13'! audioSetSample: aNumber stream: aStream "Set number of targeted sample, returns 0 if ok, -1 if failure" self hasAudio ifFalse: [^-1]. ^[self primSetSample: self fileHandle sample: aNumber asFloat stream: aStream] on: Error do: [-1] ! ! !MPEGFile methodsFor: 'audio' stamp: 'JMM 9/20/2000 01:57'! endOfAudio: aStream "Returns true if end of Audio" self hasAudio ifFalse: [^true]. ^self primEndOfAudio: self fileHandle stream: aStream ! ! !MPEGFile methodsFor: 'audio' stamp: 'JMM 9/20/2000 01:56'! hasAudio "Returns true if file has audio" ^self primHasAudio: self fileHandle ! ! !MPEGFile methodsFor: 'audio' stamp: 'JMM 9/20/2000 01:53'! totalAudioStreams "Returns total number of audio streams" ^self primTotalAudioStreams: self fileHandle ! ! !MPEGFile methodsFor: 'finalization' stamp: 'JMM 9/20/2000 02:05'! finalize self fileHandle notNil ifTrue: [self primFileClose: self fileHandle]. self fileHandle = fileBits ifTrue: [Smalltalk unregisterExternalObject: fileIndex]. fileBits _ nil. fileIndex _ 0.! ! !MPEGFile methodsFor: 'initialize-release' stamp: 'JMM 9/20/2000 01:59'! closeFile self finalize.! ! !MPEGFile methodsFor: 'initialize-release' stamp: 'JMM 9/18/2000 03:21'! initialize ! ! !MPEGFile methodsFor: 'initialize-release' stamp: 'JMM 9/20/2000 01:57'! openFile: aPath pathToFile _ aPath. fileBits _ self primFileOpen: aPath. fileBits notNil ifTrue: [fileIndex _ Smalltalk registerExternalObject: fileBits. self register.] ! ! !MPEGFile methodsFor: 'primitives' stamp: 'JMM 9/18/2000 14:19'! primAudioChannels: aHandle stream: aStream self primitiveFailed! ! !MPEGFile methodsFor: 'primitives' stamp: 'JMM 9/19/2000 13:35'! primAudioReReadBuffer: aFileHandle buffer: aBuffer channel: aChannel samples: aSampleNumber stream: aStreamNumber self primitiveFailed! ! !MPEGFile methodsFor: 'primitives' stamp: 'JMM 9/19/2000 13:31'! primAudioReadBuffer: aFileHandle buffer: aBuffer channel: aChannel samples: aSampleNumber stream: aStreamNumber self primitiveFailed! ! !MPEGFile methodsFor: 'primitives' stamp: 'JMM 9/18/2000 14:23'! primAudioSamples: aHandle stream: aStream self primitiveFailed! ! !MPEGFile methodsFor: 'primitives' stamp: 'JMM 9/18/2000 17:54'! primDropFrame: aHandle frame: aNumberOfFrames stream: aStream self primitiveFailed! ! !MPEGFile methodsFor: 'primitives' stamp: 'JMM 9/18/2000 14:50'! primEndOfAudio: aHandle stream: aStream self primitiveFailed! ! !MPEGFile methodsFor: 'primitives' stamp: 'JMM 9/18/2000 14:51'! primEndOfVideo: aHandle stream: aStream self primitiveFailed! ! !MPEGFile methodsFor: 'primitives' stamp: 'JMM 9/18/2000 13:58'! primFileClose: aHandle "Close the file" self primitiveFailed! ! !MPEGFile methodsFor: 'primitives' stamp: 'JMM 9/18/2000 03:56'! primFileOpen: aPath "Open the file" self primitiveFailed! ! !MPEGFile methodsFor: 'primitives' stamp: 'JMM 9/18/2000 14:52'! primFrameRate: aHandle stream: aStream self primitiveFailed! ! !MPEGFile methodsFor: 'primitives' stamp: 'JMM 9/29/2000 17:29'! primGenerateToc: fileHandle useSearch: timecode doStreams: streams buffer: aString self primitiveFailed! ! !MPEGFile methodsFor: 'primitives' stamp: 'JMM 9/18/2000 15:11'! primGetFrame: aHandle stream: aStream self primitiveFailed! ! !MPEGFile methodsFor: 'primitives' stamp: 'JMM 9/18/2000 15:37'! primGetPercentage: aHandle self primitiveFailed! ! !MPEGFile methodsFor: 'primitives' stamp: 'JMM 9/18/2000 15:12'! primGetSample: aHandle stream: aStream self primitiveFailed! ! !MPEGFile methodsFor: 'primitives' stamp: 'JMM 9/18/2000 15:15'! primGetTime: aFileHandle self primitiveFailed! ! !MPEGFile methodsFor: 'primitives' stamp: 'JMM 9/18/2000 14:59'! primHasAudio: aHandle self primitiveFailed! ! !MPEGFile methodsFor: 'primitives' stamp: 'JMM 9/18/2000 14:59'! primHasVideo: aHandle self primitiveFailed! ! !MPEGFile methodsFor: 'primitives' stamp: 'JMM 9/18/2000 15:17'! primPreviousFrame: aHandle stream: aStream self primitiveFailed! ! !MPEGFile methodsFor: 'primitives' stamp: 'JMM 9/18/2000 15:19'! primSampleRate: aHandle stream: aStream self primitiveFailed! ! !MPEGFile methodsFor: 'primitives' stamp: 'JMM 9/18/2000 15:23'! primSeekPercentage: aHandle percentage: aNumber self primitiveFailed! ! !MPEGFile methodsFor: 'primitives' stamp: 'JMM 9/18/2000 15:27'! primSetCPUs: aHandle number: aNumber "Not support on the macintosh below OS X" self primitiveFailed! ! !MPEGFile methodsFor: 'primitives' stamp: 'JMM 9/18/2000 15:29'! primSetFrame: aHandle frame: aFrameNumber stream: aStream self primitiveFailed! ! !MPEGFile methodsFor: 'primitives' stamp: 'JMM 9/18/2000 15:31'! primSetMMX: aFileHandle useMMX: aValue self primitiveFailed! ! !MPEGFile methodsFor: 'primitives' stamp: 'JMM 9/18/2000 15:35'! primSetSample: aHandle sample: aSampleNumber stream: aStream self primitiveFailed! ! !MPEGFile methodsFor: 'primitives' stamp: 'JMM 9/18/2000 15:39'! primTotalAudioStreams: aFileHandle self primitiveFailed! ! !MPEGFile methodsFor: 'primitives' stamp: 'JMM 9/18/2000 15:40'! primTotalVideoStreams: aFileHandle self primitiveFailed! ! !MPEGFile methodsFor: 'primitives' stamp: 'JMM 9/18/2000 15:41'! primVideoFrames: aFileHandle stream: aStream self primitiveFailed! ! !MPEGFile methodsFor: 'primitives' stamp: 'JMM 9/18/2000 15:41'! primVideoHeight: aFileHandle stream: aStream self primitiveFailed! ! !MPEGFile methodsFor: 'primitives' stamp: 'JMM 9/19/2000 13:28'! primVideoReadNextFrameFor: aFileHandle into: aFormBuffer x: x y: y width: width height: height outWidth: aTargetWidth outHeight: aTargetHeight colorModel: colorModel stream: aStream bytesPerRow: aByteCount ! ! !MPEGFile methodsFor: 'primitives' stamp: 'JMM 9/18/2000 16:35'! primVideoWidth: aFileHandle stream: aStream self primitiveFailed! ! !MPEGFile methodsFor: 'registry' stamp: 'JMM 9/17/2000 23:58'! register ^self class register: self! ! !MPEGFile methodsFor: 'registry' stamp: 'JMM 9/17/2000 23:58'! unregister ^self class unregister: self! ! !MPEGFile methodsFor: 'video' stamp: 'JMM 9/20/2000 01:54'! endOfVideo: aStream "Returns true if end of video" self hasVideo ifFalse: [^true]. ^self primEndOfVideo: self fileHandle stream: aStream ! ! !MPEGFile methodsFor: 'video' stamp: 'JMM 9/20/2000 01:54'! hasVideo "Returns true if file has video" ^self primHasVideo: self fileHandle ! ! !MPEGFile methodsFor: 'video' stamp: 'JMM 9/20/2000 01:59'! totalVideoStreams "Returns total number of video streams" ^self primTotalVideoStreams: self fileHandle ! ! !MPEGFile methodsFor: 'video' stamp: 'JMM 11/21/2000 13:14'! videoDropFrames: aNumberOfFrames stream: aStream "Returns -1 if setFrame failed" self hasVideo ifFalse: [^-1]. ^[self primDropFrame: self fileHandle frame: aNumberOfFrames stream: aStream] on: Error do: [-1] ! ! !MPEGFile methodsFor: 'video' stamp: 'JMM 11/21/2000 13:14'! videoFrameHeight: aStream "Returns video frame height, -1 if error " self hasVideo ifFalse: [^-1]. ^[self primVideoHeight: self fileHandle stream: aStream] on: Error do: [-1] ! ! !MPEGFile methodsFor: 'video' stamp: 'JMM 11/21/2000 13:14'! videoFrameRate: aStream "Returns video frame rate (float), -1 if error" self hasVideo ifFalse: [^-1]. ^[self primFrameRate: self fileHandle stream: aStream] on: Error do: [-1] ! ! !MPEGFile methodsFor: 'video' stamp: 'JMM 11/21/2000 13:14'! videoFrameWidth: aStream "Returns video frame width, -1 if error" self hasVideo ifFalse: [^-1]. ^[self primVideoWidth: self fileHandle stream: aStream] on: Error do: [-1] ! ! !MPEGFile methodsFor: 'video' stamp: 'JMM 9/20/2000 01:58'! videoFrames: aStream "Total number of frames" ^(self primVideoFrames: self fileHandle stream: aStream) asInteger ! ! !MPEGFile methodsFor: 'video' stamp: 'JMM 11/21/2000 13:14'! videoGetFrame: aStream "Returns frame number, or -1 if error" self hasVideo ifFalse: [^-1]. ^[(self primGetFrame: self fileHandle stream: aStream) asInteger] on: Error do: [-1] ! ! !MPEGFile methodsFor: 'video' stamp: 'JMM 11/21/2000 13:15'! videoPreviousFrame: aStream "Returns 0 if ok" self hasVideo ifFalse: [^-1]. ^[self primPreviousFrame: self fileHandle stream: aStream] on: Error do: [-1] ! ! !MPEGFile methodsFor: 'video' stamp: 'JMM 11/10/2000 00:24'! videoReadNext16BitFrameInto: aFormBuffer width: aTargetWidth height: aTargetHeight stream: aStream "return non zero if failure" | width height colorModel x y | width _ self videoFrameWidth: aStream. height _ self videoFrameHeight: aStream. colorModel _ self endianness = #big ifTrue: [14] ifFalse: [16]. x _ 0. y _ 0. ^self videoReadNextFrameInto: aFormBuffer x: x y: y width: width height: height outWidth: aTargetWidth outHeight: aTargetHeight colorModel: colorModel stream: aStream bytesPerRow: aTargetWidth*2 ! ! !MPEGFile methodsFor: 'video' stamp: 'JMM 11/10/2000 00:24'! videoReadNextFrameInto: aFormBuffer width: aTargetWidth height: aTargetHeight stream: aStream "return non zero if failure" | width height colorModel x y | width _ self videoFrameWidth: aStream. height _ self videoFrameHeight: aStream. colorModel _ self endianness = #big ifTrue: [13] ifFalse: [1]. x _ 0. y _ 0. ^self videoReadNextFrameInto: aFormBuffer x: x y: y width: width height: height outWidth: aTargetWidth outHeight: aTargetHeight colorModel: colorModel stream: aStream bytesPerRow: aTargetWidth*4 ! ! !MPEGFile methodsFor: 'video' stamp: 'JMM 11/21/2000 13:15'! videoReadNextFrameInto: aFormBuffer x: x y: y width: width height: height outWidth: aTargetWidth outHeight: aTargetHeight colorModel: colorModel stream: aStream bytesPerRow: aByteCount "return nonZero if failure " self hasVideo ifFalse: [^-1]. ^[self primVideoReadNextFrameFor: self fileHandle into: aFormBuffer x: x y: y width: width height: height outWidth: aTargetWidth outHeight: aTargetHeight colorModel: colorModel stream: aStream bytesPerRow: aByteCount] on: Error do: [-1] "/* Supported color models for mpeg3_read_frame */ #define MPEG3_RGB565 2 #define MPEG3_RGB555 14 //JMM for mac #define MPEG3_RGBI555 16 //SVP for intel #define MPEG3_BGR888 0 #define MPEG3_BGRA8888 1 #define MPEG3_RGB888 3 #define MPEG3_RGBA8888 4 #define MPEG3_ARGB8888 13 //JMM for mac #define MPEG3_RGBA16161616 5 /* Color models for the 601 to RGB conversion */ /* 601 not implemented for scalar code */ #define MPEG3_601_RGB565 11 #define MPEG3_601_RGB555 15 //JMM for Squeak #define MPEG3_601_RGBI555 17 //SVP for intel #define MPEG3_601_BGR888 7 #define MPEG3_601_BGRA8888 8 #define MPEG3_601_RGB888 9 #define MPEG3_601_RGBA8888 10 #define MPEG3_601_ARGB8888 12 //JMM for Squeak "! ! !MPEGFile methodsFor: 'video' stamp: 'JMM 9/20/2000 01:58'! videoSetCPUs: aNumber self primSetCPUs: self fileHandle number: aNumber! ! !MPEGFile methodsFor: 'video' stamp: 'JMM 11/21/2000 13:15'! videoSetFrame: aFrameNumber stream: aStream "Returns -1 if setFrame failed" self hasVideo ifFalse: [^-1]. ^[self primSetFrame: self fileHandle frame: aFrameNumber asFloat stream: aStream] on: Error do: [-1] ! ! !MPEGFile class methodsFor: 'registry' stamp: 'JMM 9/17/2000 23:56'! register: anObject WeakArray isFinalizationSupported ifFalse:[^anObject]. self registry add: anObject! ! !MPEGFile class methodsFor: 'registry' stamp: 'JMM 9/17/2000 23:56'! registry WeakArray isFinalizationSupported ifFalse:[^nil]. ^Registry isNil ifTrue:[Registry := WeakRegistry new] ifFalse:[Registry].! ! !MPEGFile class methodsFor: 'registry' stamp: 'JMM 9/17/2000 23:56'! unregister: anObject WeakArray isFinalizationSupported ifFalse:[^anObject]. self registry remove: anObject ifAbsent:[]! ! !MPEGFile class methodsFor: 'instance creation' stamp: 'JMM 9/18/2000 03:27'! openFile: aPath ^self new initialize openFile: aPath.! ! !MPEGFile class methodsFor: 'testing' stamp: 'JMM 9/18/2000 14:28'! isFileValidMPEG: path ^self primFileValidMPEG: path! ! !MPEGFile class methodsFor: 'primitives' stamp: 'JMM 9/18/2000 14:27'! primFileValidMPEG: aPath "Check to see if the file is valid" self primitiveFailed! ! !MPEGImageMorph methodsFor: 'drawing' stamp: 'JMM 11/8/2000 14:47'! drawOn: aCanvas aCanvas drawImage: self rotatedForm at: bounds origin ! ! !MPEGPlayer methodsFor: 'access' stamp: 'JMM 9/20/2000 13:59'! audioPlayerProcess ^audioPlayerProcess ! ! !MPEGPlayer methodsFor: 'access' stamp: 'JMM 9/20/2000 13:39'! audioPlayerProcess: aProcess audioPlayerProcess _ aProcess! ! !MPEGPlayer methodsFor: 'access' stamp: 'JMM 9/20/2000 15:31'! clockBias ^clockBias! ! !MPEGPlayer methodsFor: 'access' stamp: 'JMM 9/20/2000 15:31'! clockBias: aArray clockBias _ aArray! ! !MPEGPlayer methodsFor: 'access' stamp: 'JMM 9/20/2000 15:31'! clockBiasForStream: aStream ^self clockBias at: aStream + 1.! ! !MPEGPlayer methodsFor: 'access' stamp: 'JMM 9/20/2000 15:32'! clockBiasForStream: aStream put: aValue self clockBias at: aStream + 1 put: aValue! ! !MPEGPlayer methodsFor: 'access' stamp: 'JMM 11/8/2000 10:30'! currentAudioSampleForStream: aStream ^self external audioGetSample: aStream! ! !MPEGPlayer methodsFor: 'access' stamp: 'JMM 11/8/2000 10:31'! currentAudioSampleForStream: aStream put: aNumber self external audioSetSample: aNumber stream: aStream! ! !MPEGPlayer methodsFor: 'access' stamp: 'JMM 11/8/2000 10:29'! currentVideoFrameForStream: aStream ^self external videoGetFrame: aStream! ! !MPEGPlayer methodsFor: 'access' stamp: 'JMM 11/8/2000 10:30'! currentVideoFrameForStream: aStream put: aNumber self external videoSetFrame: aNumber stream: aStream! ! !MPEGPlayer methodsFor: 'access' stamp: 'JMM 9/20/2000 18:33'! errorForSoundStart: aValueInMilliseconds errorForSoundStart _ aValueInMilliseconds ! ! !MPEGPlayer methodsFor: 'access' stamp: 'JMM 11/19/2000 11:52'! external [external hasVideo] on: Error do: [(MPEGFile isFileValidMPEG: external fileName) ifFalse: [^self error: 'Mpeg File is invalid']. external _ MPEGFile openFile: external fileName]. ^external! ! !MPEGPlayer methodsFor: 'access' stamp: 'JMM 11/8/2000 10:31'! fileName ^self external fileName! ! !MPEGPlayer methodsFor: 'access' stamp: 'JMM 10/17/2000 23:29'! form form isNil ifTrue: [self morph isNil ifTrue: [^nil]. ^self morph form]. ^form! ! !MPEGPlayer methodsFor: 'access' stamp: 'JMM 9/20/2000 13:37'! form: aForm form _ aForm! ! !MPEGPlayer methodsFor: 'access' stamp: 'JMM 9/19/2000 17:39'! frameRate ^frameRate! ! !MPEGPlayer methodsFor: 'access' stamp: 'JMM 9/20/2000 13:36'! frameRate: aRate frameRate _ aRate! ! !MPEGPlayer methodsFor: 'access' stamp: 'JMM 9/20/2000 14:04'! lastDelay ^lastDelay! ! !MPEGPlayer methodsFor: 'access' stamp: 'JMM 9/20/2000 14:03'! lastDelay: aNumber lastDelay _ aNumber! ! !MPEGPlayer methodsFor: 'access' stamp: 'JMM 10/17/2000 23:20'! morph ^morph! ! !MPEGPlayer methodsFor: 'access' stamp: 'JMM 10/17/2000 23:20'! morph: aMorph morph _ aMorph.! ! !MPEGPlayer methodsFor: 'access' stamp: 'JMM 10/20/2000 22:36'! mpegFile ^external! ! !MPEGPlayer methodsFor: 'access' stamp: 'JMM 9/20/2000 13:59'! noSound ^noSound! ! !MPEGPlayer methodsFor: 'access' stamp: 'JMM 9/20/2000 13:59'! noSound: flag noSound _ flag! ! !MPEGPlayer methodsFor: 'access' stamp: 'JMM 9/19/2000 17:59'! playerProcessPriority ^playerProcessPriority! ! !MPEGPlayer methodsFor: 'access' stamp: 'JMM 9/19/2000 17:59'! playerProcessPriority: aNumber playerProcessPriority _ aNumber! ! !MPEGPlayer methodsFor: 'access' stamp: 'JMM 9/19/2000 17:34'! sampleRate ^sampleRate! ! !MPEGPlayer methodsFor: 'access' stamp: 'JMM 9/20/2000 13:36'! sampleRate: aRate sampleRate _ aRate! ! !MPEGPlayer methodsFor: 'access' stamp: 'JMM 9/20/2000 14:01'! soundQueue ^soundQueue! ! !MPEGPlayer methodsFor: 'access' stamp: 'JMM 9/20/2000 14:01'! soundQueue: aQueue soundQueue _ aQueue! ! !MPEGPlayer methodsFor: 'access' stamp: 'JMM 9/20/2000 14:38'! startTime ^startTime! ! !MPEGPlayer methodsFor: 'access' stamp: 'JMM 9/20/2000 14:38'! startTime: aArray startTime _ aArray! ! !MPEGPlayer methodsFor: 'access' stamp: 'JMM 9/20/2000 15:12'! startTimeForStream: aStream ^self startTime at: aStream + 1! ! !MPEGPlayer methodsFor: 'access' stamp: 'JMM 9/20/2000 15:11'! startTimeForStream: aStream put: aNumber ^self startTime at: aStream + 1 put: aNumber! ! !MPEGPlayer methodsFor: 'access' stamp: 'JMM 9/20/2000 14:03'! timeCheck ^timeCheck! ! !MPEGPlayer methodsFor: 'access' stamp: 'JMM 9/20/2000 14:02'! timeCheck: aNumber timeCheck _ aNumber! ! !MPEGPlayer methodsFor: 'access' stamp: 'JMM 9/20/2000 13:58'! videoPlayerProcess ^videoPlayerProcess ! ! !MPEGPlayer methodsFor: 'access' stamp: 'JMM 9/20/2000 13:58'! videoPlayerProcess: aProcess videoPlayerProcess _ aProcess! ! !MPEGPlayer methodsFor: 'access' stamp: 'kfr 11/9/2000 21:21'! volume: aVolume volume _ aVolume! ! !MPEGPlayer methodsFor: 'access to attributes' stamp: 'JMM 11/8/2000 10:29'! audioChannels: aStream ^self external audioChannels: aStream! ! !MPEGPlayer methodsFor: 'access to attributes' stamp: 'JMM 11/8/2000 10:31'! audioSampleRate: aStream ^self external audioSampleRate: aStream! ! !MPEGPlayer methodsFor: 'access to attributes' stamp: 'JMM 11/8/2000 10:33'! audioSamples: aStream ^self external audioSamples: aStream ! ! !MPEGPlayer methodsFor: 'access to attributes' stamp: 'JMM 11/13/2000 20:05'! currentExternalLocationInPercent "Warning this might not return what you want, it gets percentage based on audio, or video stream based on last usage, because we buffer audio it may give incorrect information when playing mpeg movies" ^self external getPercentage! ! !MPEGPlayer methodsFor: 'access to attributes' stamp: 'JMM 11/13/2000 20:09'! currentLocationInPercent: aStream self hasVideo ifTrue: [^ ((self currentVideoFrameForStream: aStream)/(self videoFrames: aStream)) asFloat]. self hasAudio ifTrue: [^ ((self currentAudioSampleForStream: aStream)/(self audioSamples: aStream)) asFloat]. ! ! !MPEGPlayer methodsFor: 'access to attributes' stamp: 'JMM 11/8/2000 10:32'! endOfAudio: aStream ^self external endOfAudio: aStream ! ! !MPEGPlayer methodsFor: 'access to attributes' stamp: 'JMM 11/8/2000 10:30'! endOfVideo: aStream ^self external endOfVideo: aStream ! ! !MPEGPlayer methodsFor: 'access to attributes' stamp: 'JMM 11/8/2000 10:33'! getTOC: timecode doStreams: streams ^self external getTOC: timecode doStreams: streams ! ! !MPEGPlayer methodsFor: 'access to attributes' stamp: 'JMM 11/8/2000 10:31'! getTimeCode ^self external getTimeCode! ! !MPEGPlayer methodsFor: 'access to attributes' stamp: 'JMM 11/8/2000 10:31'! hasAudio ^self external hasAudio ! ! !MPEGPlayer methodsFor: 'access to attributes' stamp: 'JMM 11/8/2000 10:30'! hasVideo ^self external hasVideo! ! !MPEGPlayer methodsFor: 'access to attributes' stamp: 'JMM 11/8/2000 10:31'! setMMX: aBoolean self external setMMX: aBoolean! ! !MPEGPlayer methodsFor: 'access to attributes' stamp: 'JMM 11/8/2000 10:33'! totalVideoStreams ^self external totalVideoStreams ! ! !MPEGPlayer methodsFor: 'access to attributes' stamp: 'JMM 11/8/2000 10:32'! videoDropFrames: aNumberOfFrames stream: aStream ^self external videoDropFrames: aNumberOfFrames stream: aStream! ! !MPEGPlayer methodsFor: 'access to attributes' stamp: 'JMM 11/8/2000 10:30'! videoFrameHeight: aStream ^self external videoFrameHeight: aStream ! ! !MPEGPlayer methodsFor: 'access to attributes' stamp: 'JMM 11/8/2000 10:29'! videoFrameRate: aStream ^self external videoFrameRate: aStream! ! !MPEGPlayer methodsFor: 'access to attributes' stamp: 'JMM 11/8/2000 10:29'! videoFrameWidth: aStream ^self external videoFrameWidth: aStream ! ! !MPEGPlayer methodsFor: 'access to attributes' stamp: 'JMM 11/8/2000 10:33'! videoFrames: aStream ^self external videoFrames: aStream ! ! !MPEGPlayer methodsFor: 'access to attributes' stamp: 'JMM 11/8/2000 10:33'! videoPreviousFrame: aStream ^self external videoPreviousFrame: aStream ! ! !MPEGPlayer methodsFor: 'access to attributes' stamp: 'JMM 11/8/2000 10:33'! videoSetCPUs: aNumber ^self external videoSetCPUs: aNumber ! ! !MPEGPlayer methodsFor: 'audio' stamp: 'kfr 11/9/2000 22:26'! createSoundFrom: aStream | snds channels | snds _ OrderedCollection new. channels _ self audioChannels: 0. 1 to: channels do: [:c | snds add: (self readSoundChannel: c - 1 stream: aStream)]. channels = 1 ifTrue:[^ MixedSound new add: (snds at: 1) pan: 0.5 volume: volume; yourself] ifFalse: [ ^ MixedSound new add: (snds at: 1) pan: 0.0 volume: volume; add: (snds at: 2) pan: 1.0 volume: volume; yourself].! ! !MPEGPlayer methodsFor: 'audio' stamp: 'JMM 11/19/2000 18:03'! privatePlayAudioStream: aStream | number | number _ 5. self soundQueue: (QueueSound new startTime: 0). [number + 2 timesRepeat: [self soundQueue add: (self createSoundFrom: aStream)]. self soundQueue play. semaphoreForSound signal. [[self soundQueue sounds size > number] whileTrue: [(Delay forMilliseconds: 100) wait]. self soundQueue add: (self createSoundFrom: aStream). (self endOfAudio: aStream) ifTrue: [self audioPlayerProcess: nil. ^self]] repeat] on: Error do: [self audioPlayerProcess: nil. ^self]! ! !MPEGPlayer methodsFor: 'audio' stamp: 'JMM 11/19/2000 18:02'! readSoundChannel: aChannel stream: aStream | buffer result samples | samples _ (self sampleRate // 10) min: ((self audioSamples: aStream) - (self currentAudioSampleForStream: aStream)). (samples == 0) ifTrue: [self error: 'Mpeg at end of stream, toss error, catch up high']. buffer _ SoundBuffer newMonoSampleCount: samples. aChannel = 0 ifTrue: [result _ self external audioReadBuffer: buffer stream: aStream channel: aChannel] ifFalse: [result _ self external audioReReadBuffer: buffer stream: aStream channel: aChannel]. ^SampledSound samples: buffer samplingRate: self sampleRate. ! ! !MPEGPlayer methodsFor: 'audio' stamp: 'JMM 11/8/2000 10:49'! setupStream: aStream self sampleRate: (self audioSampleRate: aStream). SoundPlayer startPlayerProcessBufferSize: 8192 "(SoundPlayer bufferMSecs * self sampleRate) // 1000" rate: self sampleRate stereo: true. ! ! !MPEGPlayer methodsFor: 'audio' stamp: 'JMM 11/8/2000 10:33'! setupStreamNoSeek: aStream self sampleRate: (self audioSampleRate: aStream). SoundPlayer startPlayerProcessBufferSize: 8192 "(SoundPlayer bufferMSecs * self sampleRate) // 1000" rate: self sampleRate stereo: ((self audioChannels: aStream) > 1). ! ! !MPEGPlayer methodsFor: 'audio' stamp: 'JMM 9/20/2000 13:38'! startAudioPlayerProcess: aStream self audioPlayerProcess: ([self privatePlayAudioStream: aStream] forkAt: Processor userInterruptPriority)! ! !MPEGPlayer methodsFor: 'audio' stamp: 'JMM 9/19/2000 16:59'! updateSoundStream: aStream! ! !MPEGPlayer methodsFor: 'delay' stamp: 'JMM 11/8/2000 15:30'! calculateDelayGivenFrame: frame stream: aStream | estimated current delta | current _ Time millisecondClockValue - (self startTimeForStream: aStream). estimated _ ((frame asFloat / self frameRate) * 1000) asInteger - (self clockBiasForStream: aStream). delta _ estimated - current. delta > 33 ifTrue: [self lastDelay: (delta + self lastDelay) // 2. (Delay forMilliseconds: self lastDelay) wait]. delta < -33 ifTrue: [self lastDelay: self lastDelay // 2. self decideToSkipAFrame: delta averageWait: current//frame stream: aStream]. ! ! !MPEGPlayer methodsFor: 'delay' stamp: 'JMM 11/8/2000 10:13'! calculateDelayToSoundGivenFrame: frame stream: aStream | current delta buffers estimatedAudio estimatedVideo | current _ Time millisecondClockValue - (self startTimeForStream: aStream) + (self clockBiasForStream: aStream). buffers _ (self soundQueue sounds size - 1 ) max: 0. buffers = 0 ifTrue: [^self]. estimatedAudio _ ((self currentAudioSampleForStream: aStream) - (buffers * self sampleRate // 10) - self soundQueue currentSound samplesRemaining) * 1000 / self sampleRate. estimatedAudio _ estimatedAudio - 0000. estimatedVideo _ ((frame asFloat / self frameRate) * 1000) asInteger. delta _ estimatedVideo - estimatedAudio. delta > 100 ifTrue: [self lastDelay < delta ifTrue: [self lastDelay: self lastDelay + (((delta-self lastDelay)/10) max: 1)]. (Delay forMilliseconds: self lastDelay) wait]. delta < -100 ifTrue: [self lastDelay: ((self lastDelay - 10) max: 1). self decideToSkipAFrame: delta averageWait: current//frame stream: aStream]. ! ! !MPEGPlayer methodsFor: 'delay' stamp: 'JMM 11/8/2000 14:28'! decideToSkipAFrame: delta averageWait: aWaitTime stream: aStream | estimatedFrames | delta abs > aWaitTime ifTrue: [estimatedFrames _ ( delta abs / (1000 / self frameRate)) asInteger. self videoDropFrames: estimatedFrames stream: aStream].! ! !MPEGPlayer methodsFor: 'initialize-release' stamp: 'JMM 11/8/2000 10:31'! close self external closeFile! ! !MPEGPlayer methodsFor: 'initialize-release' stamp: 'kfr 11/9/2000 21:19'! initialize: aPath (MPEGFile isFileValidMPEG: aPath) ifFalse: [^nil]. external _ MPEGFile openFile: aPath. self playerProcessPriority: Processor userSchedulingPriority. self lastDelay: 10. volume _ 1.0. errorForSoundStart _ 500. semaphoreForSound _ Semaphore new. self startTime: (Array new: self totalVideoStreams). self clockBias: (Array new: self totalVideoStreams withAll: 0).! ! !MPEGPlayer methodsFor: 'initialize-release' stamp: 'JMM 9/20/2000 14:06'! initializeWithFileName: aPath self initialize: aPath. self form: nil. ^self! ! !MPEGPlayer methodsFor: 'initialize-release' stamp: 'JMM 9/20/2000 14:06'! initializeWithFileName: aPath form: aForm self initialize: aPath. self form: aForm. ^self! ! !MPEGPlayer methodsFor: 'initialize-release' stamp: 'JMM 10/17/2000 23:34'! initializeWithFileName: aPath morph: aMorphic self initialize: aPath. self morph: aMorphic. ^self! ! !MPEGPlayer methodsFor: 'initialize-release' stamp: 'JMM 9/20/2000 14:15'! stopAndClose self stop. self close ! ! !MPEGPlayer methodsFor: 'play' stamp: 'JMM 11/8/2000 10:20'! playAudioStream: aStream self hasAudio ifFalse: [^self]. self setupStream: aStream. self startAudioPlayerProcess: aStream.! ! !MPEGPlayer methodsFor: 'play' stamp: 'JMM 11/8/2000 10:20'! playAudioStreamNoSeek: aStream self hasAudio ifFalse: [^self]. self setupStreamNoSeek: aStream. self startAudioPlayerProcess: aStream.! ! !MPEGPlayer methodsFor: 'play' stamp: 'JMM 11/8/2000 10:20'! playAudioStreamWaitTilDone: aStream self hasAudio ifFalse: [^self]. self setupStream: aStream. self privatePlayAudioStream: aStream.! ! !MPEGPlayer methodsFor: 'play' stamp: 'JMM 11/8/2000 10:20'! playStream: aStream self noSound: self hasAudio not. self startVideoPlayerProcess: aStream ! ! !MPEGPlayer methodsFor: 'play' stamp: 'JMM 11/8/2000 10:20'! playStreamWaitTilDone: aStream self noSound: self hasAudio not. self privatePlayVideoStream: aStream.! ! !MPEGPlayer methodsFor: 'play' stamp: 'JMM 9/20/2000 14:00'! playVideoStream: aStream self noSound: true. self startVideoPlayerProcess: aStream ! ! !MPEGPlayer methodsFor: 'play' stamp: 'JMM 9/20/2000 14:00'! playVideoStreamWaitTilDone: aStream self noSound: true. self privatePlayVideoStream: aStream ! ! !MPEGPlayer methodsFor: 'play controls' stamp: 'JMM 11/8/2000 10:38'! backAudio: aNumber forStream: aStream self forwardAudio: (0-aNumber) forStream: aStream! ! !MPEGPlayer methodsFor: 'play controls' stamp: 'JMM 11/8/2000 10:39'! backVideo: aNumber forStream: aStream self forwardVideo: (0-aNumber) forStream: aStream! ! !MPEGPlayer methodsFor: 'play controls' stamp: 'JMM 11/13/2000 19:35'! forwardAudio: aNumber forStream: aStream | newLocation | self hasAudio ifFalse: [^self]. newLocation _ (((self currentAudioSampleForStream: aStream) + aNumber) min: (self audioSamples: aStream)) max: 0 . self currentAudioSampleForStream: aStream put: newLocation! ! !MPEGPlayer methodsFor: 'play controls' stamp: 'JMM 11/13/2000 19:35'! forwardVideo: aNumber forStream: aStream | newLocation | self hasVideo ifFalse: [^self]. newLocation _ (((self currentVideoFrameForStream: aStream) + aNumber) min: (self videoFrames: aStream)) max: 0. self currentVideoFrameForStream: aStream put: newLocation. ! ! !MPEGPlayer methodsFor: 'play controls' stamp: 'JMM 11/19/2000 12:50'! isPlaying ^((self audioPlayerProcess isNil) and: [self videoPlayerProcess isNil]) not! ! !MPEGPlayer methodsFor: 'play controls' stamp: 'JMM 11/13/2000 19:37'! recalculateNewSampleLocationForStream: aStream givenFrame: aFrame | estimated | self hasAudio ifFalse: [^self]. estimated _ (aFrame / (self videoFrames: aStream) * (self audioSampleRate: aStream)) asInteger. self currentAudioSampleForStream: aStream put: estimated.! ! !MPEGPlayer methodsFor: 'play controls' stamp: 'JMM 11/8/2000 10:47'! seekToHere: aPercentage forStream: aStream "Alternate method is to seek all video/audio for stream to a certain percentage using the primitive, but I think your mpeg must have timecodes!! otherwise endless loop" self external seekPercentage: aPercentage! ! !MPEGPlayer methodsFor: 'play controls' stamp: 'JMM 11/19/2000 11:44'! seekVideoAudioBasedOnFrame: aFrame forStream: aStream self external hasVideo ifTrue: [self currentVideoFrameForStream: aStream put: aFrame]. self recalculateNewSampleLocationForStream: aStream givenFrame: aFrame! ! !MPEGPlayer methodsFor: 'play controls' stamp: 'JMM 11/10/2000 00:19'! setLocation: aPercentage forStream: aStream self hasAudio ifTrue: [self currentAudioSampleForStream: aStream put: ((self audioSamples: aStream) * aPercentage) asInteger]. self hasVideo ifTrue: [self currentVideoFrameForStream: aStream put: ((self videoFrames: aStream) * aPercentage) asInteger].! ! !MPEGPlayer methodsFor: 'play controls' stamp: 'JMM 9/20/2000 18:46'! stop self videoPlayerProcess notNil ifTrue: [self videoPlayerProcess terminate. self videoPlayerProcess: nil]. self audioPlayerProcess notNil ifTrue: [self audioPlayerProcess terminate. self audioPlayerProcess: nil. SoundPlayer stopPlayingAll]! ! !MPEGPlayer methodsFor: 'utility' stamp: 'JMM 10/17/2000 23:22'! changed self morph notNil ifTrue: [self morph changed].! ! !MPEGPlayer methodsFor: 'utility' stamp: 'JMM 11/8/2000 10:25'! checkForm: aStream | y x | self form notNil ifTrue: [^self]. y _ self videoFrameHeight: aStream. x _ self videoFrameWidth: aStream. self form: (Form extent: x@y depth: 32) ! ! !MPEGPlayer methodsFor: 'video' stamp: 'JMM 11/19/2000 12:47'! privatePlayVideoStream: aStream | location | self hasVideo ifFalse: [self timeCheck: 0@0. ^self]. self checkForm: aStream. self frameRate: (self videoFrameRate: aStream). location _ self currentVideoFrameForStream: aStream. self clockBiasForStream: aStream put: (1/self frameRate*location*1000) asInteger. self videoLoop: aStream. self timeCheck: ((Time millisecondClockValue + (self clockBiasForStream: aStream) - (self startTimeForStream: aStream))/1000.0) @ ((self videoFrames: aStream) / self frameRate). self videoPlayerProcess: nil! ! !MPEGPlayer methodsFor: 'video' stamp: 'JMM 9/20/2000 13:59'! startVideoPlayerProcess: aStream self videoPlayerProcess: ([self privatePlayVideoStream: aStream] forkAt: self playerProcessPriority)! ! !MPEGPlayer methodsFor: 'video' stamp: 'JMM 11/19/2000 12:45'! videoLoop: aStream | location oneTime | oneTime _ true. [self form depth = 16 ifTrue: [self external videoReadNext16BitFrameInto: self form bits width: self form width height: self form height stream: aStream] ifFalse: [self external videoReadNextFrameInto: self form bits width: self form width height: self form height stream: aStream]. oneTime ifTrue: [oneTime _ false. self noSound ifFalse: [self playAudioStreamNoSeek: aStream. semaphoreForSound wait. (Delay forMilliseconds: errorForSoundStart) wait]. self startTimeForStream: aStream put: (Time millisecondClockValue)]. self morph ifNil: [self form == Display ifTrue: [Display forceToScreen] ifFalse: [self form displayOn: Display]]. self changed. location _ (self currentVideoFrameForStream: aStream)+1. true ifTrue: [self calculateDelayGivenFrame: location stream: aStream] ifFalse: [self calculateDelayToSoundGivenFrame: location stream: aStream]. (self endOfVideo: aStream) ifTrue: [^self]] repeat.! ! !MPEGPlayer class methodsFor: 'instance creation' stamp: 'JMM 9/18/2000 19:02'! playFile: aPath ^self new initializeWithFileName: aPath ! ! !MPEGPlayer class methodsFor: 'instance creation' stamp: 'JMM 9/18/2000 18:32'! playFile: aPath onForm: aForm ^self new initializeWithFileName: aPath form: aForm! ! !MPEGPlayer class methodsFor: 'instance creation' stamp: 'JMM 10/17/2000 23:19'! playFile: aPath onMorph: aMorph ^self new initializeWithFileName: aPath morph: aMorph! ! !Mpeg3Plugin methodsFor: 'support' stamp: 'JMM 10/2/2000 12:14'! checkFileEntry: aMpegFile self var: #aMpegFile declareC: 'mpeg3_t * aMpegFile'. 1 to: maximumNumberOfFilesToWatch do: [:i | ((mpegFiles at: i) = aMpegFile) ifTrue: [^true]]. ^false. ! ! !Mpeg3Plugin methodsFor: 'support' stamp: 'JMM 10/2/2000 11:44'! initialiseModule self export: true. maximumNumberOfFilesToWatch _ 1024. 1 to: maximumNumberOfFilesToWatch do: [:i | mpegFiles at: i put: 0]. ^self cCode: 'true' inSmalltalk:[true]! ! !Mpeg3Plugin methodsFor: 'support' stamp: 'JMM 10/2/2000 12:16'! makeFileEntry: aMpegFile self var: #aMpegFile declareC: 'mpeg3_t * aMpegFile'. 1 to: maximumNumberOfFilesToWatch do: [:i | ((mpegFiles at: i) = 0) ifTrue: [mpegFiles at: i put: aMpegFile. ^true]]. ^false "Ok no room just ignore, we'll get a primitive failure later" ! ! !Mpeg3Plugin methodsFor: 'support' stamp: 'JMM 10/2/2000 11:55'! mpeg3tValueOf: mpeg3tHandle "Return a pointer to the first byte of of the mpeg3_t record within the given Smalltalk object, or nil if socketOop is not a mpeg3_t record." | index check | self returnTypeC: 'mpeg3_t *'. self var: #index declareC: 'mpeg3_t ** index'. interpreterProxy success: ((interpreterProxy isBytes: mpeg3tHandle) and: [(interpreterProxy byteSizeOf: mpeg3tHandle) = 4]). interpreterProxy failed ifTrue: [^ nil] ifFalse: [index _ self cCoerce: (interpreterProxy firstIndexableField: mpeg3tHandle) to: 'mpeg3_t **'. self cCode: 'check = checkFileEntry(*index)'. check = 0 ifTrue: [^nil]. ^ self cCode: '*index']! ! !Mpeg3Plugin methodsFor: 'support' stamp: 'JMM 10/2/2000 12:14'! removeFileEntry: aMpegFile self var: #aMpegFile declareC: 'mpeg3_t * aMpegFile'. 1 to: maximumNumberOfFilesToWatch do: [:i | ((mpegFiles at: i) = aMpegFile) ifTrue: [mpegFiles at: i put: 0. ^true]]. "Just ignore" ^false ! ! !Mpeg3Plugin methodsFor: 'support' stamp: 'JMM 10/2/2000 12:03'! shutdownModule self export: true. 1 to: maximumNumberOfFilesToWatch do: [:i | ((mpegFiles at: i) ~= 0) ifTrue: [self cCode: 'mpeg3_close(mpegFiles[i])'. mpegFiles at: i put: 0]]. ^self cCode: 'true' inSmalltalk:[true]! ! !Mpeg3Plugin methodsFor: 'primitives' stamp: 'ls 11/4/2000 13:27'! primitiveMPEG3AudioChannels: fileHandle stream: aNumber | file result | "int mpeg3_audio_channels(mpeg3_t *file,int stream)" self var: #file declareC: 'mpeg3_t * file'. self primitive: 'primitiveMPEG3AudioChannels' parameters: #(Oop SmallInteger). file _ self mpeg3tValueOf: fileHandle. file = nil ifTrue: [^0]. aNumber < 0 ifTrue: [interpreterProxy success: false. ^0]. aNumber >= (self cCode: 'mpeg3_total_astreams(file)') ifTrue: [ interpreterProxy success: false. ^0. ]. result := self cCode: 'mpeg3_audio_channels(file,aNumber)'. ^result asSmallIntegerObj ! ! !Mpeg3Plugin methodsFor: 'primitives' stamp: 'ls 11/4/2000 13:26'! primitiveMPEG3AudioSamples: fileHandle stream: aNumber | file result | "long mpeg3_audio_samples(mpeg3_t *file, int stream)" self var: #file declareC: 'mpeg3_t * file'. self primitive: 'primitiveMPEG3AudioSamples' parameters: #(Oop SmallInteger). file _ self mpeg3tValueOf: fileHandle. file = nil ifTrue: [^0]. aNumber < 0 ifTrue: [interpreterProxy success: false. ^nil]. aNumber >= (self cCode: 'mpeg3_total_astreams(file)') ifTrue: [ interpreterProxy success: false. ^0. ]. self cCode: 'result = mpeg3_audio_samples(file,aNumber)'. ^result asOop: Float ! ! !Mpeg3Plugin methodsFor: 'primitives' stamp: 'JMM 9/18/2000 20:11'! primitiveMPEG3CheckSig: path | result sz storage | "int mpeg3_check_sig(char *path)" self var: #storage declareC: 'char storage[1024] '. self primitive: 'primitiveMPEG3CheckSig' parameters: #(String). sz _ interpreterProxy byteSizeOf: path cPtrAsOop. self cCode: 'strncpy(storage,path,sz)'. storage at: sz put: 0. self cCode: 'result = mpeg3_check_sig(storage)'. ^result asOop: Boolean ! ! !Mpeg3Plugin methodsFor: 'primitives' stamp: 'JMM 10/2/2000 11:52'! primitiveMPEG3Close: fileHandle | file index | "int mpeg3_close(mpeg3_t *file)" self var: #file declareC: 'mpeg3_t * file'. self var: #index declareC: 'mpeg3_t ** index'. self primitive: 'primitiveMPEG3Close' parameters: #(Oop). file _ self mpeg3tValueOf: fileHandle. file = nil ifTrue: [^nil]. self cCode: 'removeFileEntry(file); mpeg3_close(file)'. index _ self cCoerce: (interpreterProxy firstIndexableField: fileHandle) to: 'mpeg3_t **'. self cCode: '*index = 0'. ! ! !Mpeg3Plugin methodsFor: 'primitives' stamp: 'ls 11/4/2000 13:41'! primitiveMPEG3DropFrames: fileHandle frames: aFrameNumber stream: aNumber | file result | "int mpeg3_drop_frames(mpeg3_t *file, long frames, int stream)" self var: #file declareC: 'mpeg3_t * file'. self primitive: 'primitiveMPEG3DropFrames' parameters: #(Oop SmallInteger SmallInteger). file _ self mpeg3tValueOf: fileHandle. file = nil ifTrue: [^0]. aNumber < 0 ifTrue: [interpreterProxy success: false. ^nil]. aNumber >= (self cCode: 'result = mpeg3_total_vstreams(file)') ifTrue: [ interpreterProxy success: false. ^0 ]. self cCode: 'result = mpeg3_drop_frames(file,aFrameNumber,aNumber)'. ^result asSmallIntegerObj ! ! !Mpeg3Plugin methodsFor: 'primitives' stamp: 'ls 11/4/2000 13:41'! primitiveMPEG3EndOfAudio: fileHandle stream: aNumber | file result | "int mpeg3_end_of_audio(mpeg3_t *file, int stream)" self var: #file declareC: 'mpeg3_t * file'. self primitive: 'primitiveMPEG3EndOfAudio' parameters: #(Oop SmallInteger). file _ self mpeg3tValueOf: fileHandle. file = nil ifTrue: [^0]. aNumber < 0 ifTrue: [interpreterProxy success: false. ^nil]. aNumber >= (self cCode: 'result = mpeg3_total_astreams(file)') ifTrue: [ interpreterProxy success: false. ^0 ]. self cCode: 'result = mpeg3_end_of_audio(file,aNumber)'. ^result asOop: Boolean ! ! !Mpeg3Plugin methodsFor: 'primitives' stamp: 'ls 11/4/2000 13:58'! primitiveMPEG3EndOfVideo: fileHandle stream: aNumber | file result | "int mpeg3_end_of_video(mpeg3_t *file, int stream)" self var: #file declareC: 'mpeg3_t * file'. self primitive: 'primitiveMPEG3EndOfVideo' parameters: #(Oop SmallInteger). file _ self mpeg3tValueOf: fileHandle. file = nil ifTrue: [^0]. aNumber < 0 ifTrue: [interpreterProxy success: false. ^nil]. aNumber >= (self cCode: 'result = mpeg3_total_vstreams(file)') ifTrue: [ interpreterProxy success: false. ^0 ]. self cCode: 'result = mpeg3_end_of_video(file,aNumber)'. ^result asOop: Boolean ! ! !Mpeg3Plugin methodsFor: 'primitives' stamp: 'ls 11/4/2000 13:59'! primitiveMPEG3FrameRate: fileHandle stream: aNumber | file result | "float mpeg3_frame_rate(mpeg3_t *file, int stream)" self var: #result declareC: 'double result'. self var: #file declareC: 'mpeg3_t * file'. self primitive: 'primitiveMPEG3FrameRate' parameters: #(Oop SmallInteger). file _ self mpeg3tValueOf: fileHandle. file = nil ifTrue: [^0]. aNumber < 0 ifTrue: [interpreterProxy success: false. ^nil]. aNumber >= (self cCode: 'result = mpeg3_total_vstreams(file)') ifTrue: [ interpreterProxy success: false. ^0 ]. self cCode: 'result = mpeg3_frame_rate(file,aNumber)'. ^result asOop: Float ! ! !Mpeg3Plugin methodsFor: 'primitives' stamp: 'JMM 10/2/2000 12:19'! primitiveMPEG3GenerateToc: fileHandle useSearch: timecode doStreams: streams buffer: aString | file bufferSize | "int mpeg3_generate_toc_for_Squeak(FILE *output, char *path, int timecode_search, int print_streams, char *buffer)" self var: #file declareC: 'mpeg3_t * file'. self primitive: 'primitiveMPEG3GenerateToc' parameters: #(Oop SmallInteger Boolean String). file _ self mpeg3tValueOf: fileHandle. file = nil ifTrue: [^nil]. bufferSize _ interpreterProxy slotSizeOf: (interpreterProxy stackValue: 0). self cCode: 'mpeg3_generate_toc_for_Squeak(file,timecode,streams,aString,bufferSize)'. ! ! !Mpeg3Plugin methodsFor: 'primitives' stamp: 'ls 11/4/2000 13:59'! primitiveMPEG3GetFrame: fileHandle stream: aNumber | file result | "long mpeg3_get_frame(mpeg3_t *file,int stream)" self var: #file declareC: 'mpeg3_t * file'. self primitive: 'primitiveMPEG3GetFrame' parameters: #(Oop SmallInteger). file _ self mpeg3tValueOf: fileHandle. file = nil ifTrue: [^0]. aNumber < 0 ifTrue: [interpreterProxy success: false. ^nil]. aNumber >= (self cCode: 'result = mpeg3_total_vstreams(file)') ifTrue: [ interpreterProxy success: false. ^0 ]. self cCode: 'result = mpeg3_get_frame(file,aNumber)'. ^result asOop: Float. ! ! !Mpeg3Plugin methodsFor: 'primitives' stamp: 'ls 11/4/2000 13:59'! primitiveMPEG3GetSample: fileHandle stream: aNumber | file result | "int mpeg3_video_width(mpeg3_t *file, int stream)" self var: #file declareC: 'mpeg3_t * file'. self primitive: 'primitiveMPEG3GetSample' parameters: #(Oop SmallInteger). file _ self mpeg3tValueOf: fileHandle. file = nil ifTrue: [^0]. aNumber < 0 ifTrue: [interpreterProxy success: false. ^nil]. aNumber >= (self cCode: 'result = mpeg3_total_astreams(file)') ifTrue: [ interpreterProxy success: false. ^0 ]. self cCode: 'result = mpeg3_get_sample(file,aNumber)'. ^result asOop: Float ! ! !Mpeg3Plugin methodsFor: 'primitives' stamp: 'JMM 9/18/2000 00:55'! primitiveMPEG3GetTime: fileHandle | file result | "double mpeg3_get_time(mpeg3_t *file)" self var: # result declareC: 'double result'. self var: #file declareC: 'mpeg3_t * file'. self primitive: 'primitiveMPEG3GetTime' parameters: #(Oop). file _ self mpeg3tValueOf: fileHandle. file = nil ifTrue: [^nil]. self cCode: 'result = mpeg3_get_time(file)'. ^result asOop: Float. ! ! !Mpeg3Plugin methodsFor: 'primitives' stamp: 'JMM 9/18/2000 14:33'! primitiveMPEG3HasAudio: fileHandle | file result | "int mpeg3_has_audio(mpeg3_t *file)" self var: #file declareC: 'mpeg3_t * file'. self primitive: 'primitiveMPEG3HasAudio' parameters: #(Oop). file _ self mpeg3tValueOf: fileHandle. file = nil ifTrue: [^nil]. self cCode: 'result = mpeg3_has_audio(file)'. ^result asOop: Boolean ! ! !Mpeg3Plugin methodsFor: 'primitives' stamp: 'JMM 9/18/2000 14:57'! primitiveMPEG3HasVideo: fileHandle | file result | "int mpeg3_has_video(mpeg3_t *file)" self var: #file declareC: 'mpeg3_t * file'. self primitive: 'primitiveMPEG3HasVideo' parameters: #(Oop). file _ self mpeg3tValueOf: fileHandle. file = nil ifTrue: [^nil]. self cCode: 'result = mpeg3_has_video(file)'. ^result asOop: Boolean ! ! !Mpeg3Plugin methodsFor: 'primitives' stamp: 'JMM 10/2/2000 11:51'! primitiveMPEG3Open: path | mpeg3Oop index sz storage | "mpeg3_t* mpeg3_open(char *path)" self var: #index declareC: 'mpeg3_t ** index'. self var: #storage declareC: 'char storage[1024]'. self primitive: 'primitiveMPEG3Open' parameters: #(String). sz _ interpreterProxy byteSizeOf: path cPtrAsOop. self cCode: 'strncpy(storage,path,sz)'. storage at: sz put: 0. mpeg3Oop _ interpreterProxy instantiateClass: interpreterProxy classByteArray indexableSize: 4. index _ self cCoerce: (interpreterProxy firstIndexableField: mpeg3Oop) to: 'mpeg3_t **'. self cCode: '*index = mpeg3_open(storage); makeFileEntry(*index)'. ^mpeg3Oop. ! ! !Mpeg3Plugin methodsFor: 'primitives' stamp: 'ls 11/4/2000 14:00'! primitiveMPEG3PreviousFrame: fileHandle stream: aNumber | file result | "int mpeg3_previous_frame(mpeg3_t *file, int stream)" self var: #file declareC: 'mpeg3_t * file'. self primitive: 'primitiveMPEG3PreviousFrame' parameters: #(Oop SmallInteger). file _ self mpeg3tValueOf: fileHandle. aNumber < 0 ifTrue: [interpreterProxy success: false. ^nil]. file = nil ifTrue: [^nil]. aNumber >= (self cCode: 'result = mpeg3_total_vstreams(file)') ifTrue: [ interpreterProxy success: false. ^0 ]. self cCode: 'result = mpeg3_previous_frame(file,aNumber)'. ^result asSmallIntegerObj ! ! !Mpeg3Plugin methodsFor: 'primitives' stamp: 'ls 11/4/2000 14:09'! primitiveMPEG3ReReadAudio: fileHandle shortArray: anArray channel: aChannelNumber samples: aSampleNumber stream: aNumber | file result arrayBase | "int mpeg3_reread_audio(mpeg3_t *file, float *output_f, short *output_i, int channel, long samples, int stream)" self var: #file declareC: 'mpeg3_t * file'. self var: #arrayBase declareC: 'short * arrayBase'. self primitive: 'primitiveMPEG3ReReadAudio' parameters: #(Oop Array SmallInteger SmallInteger SmallInteger). file _ self mpeg3tValueOf: fileHandle. file = nil ifTrue: [^0]. aNumber < 0 ifTrue: [interpreterProxy success: false. ^nil]. aNumber >= (self cCode: 'result = mpeg3_total_astreams(file)') ifTrue: [ interpreterProxy success: false. ^0 ]. arrayBase _ self cCoerce: anArray to: 'short *'. interpreterProxy failed ifTrue: [^nil]. self cCode: 'result = mpeg3_reread_audio(file,(float *) NULL,arrayBase,aChannelNumber,aSampleNumber,aNumber)'. ^result asSmallIntegerObj ! ! !Mpeg3Plugin methodsFor: 'primitives' stamp: 'ls 11/4/2000 14:09'! primitiveMPEG3ReadAudio: fileHandle shortArray: anArray channel: aChannelNumber samples: aSampleNumber stream: aNumber | file result arrayBase | "int mpeg3_read_audio(mpeg3_t *file, float *output_f, short *output_i, int channel, long samples, int stream)" self var: #file declareC: 'mpeg3_t * file'. self var: #arrayBase declareC: 'short * arrayBase'. self primitive: 'primitiveMPEG3ReadAudio' parameters: #(Oop Array SmallInteger SmallInteger SmallInteger). file _ self mpeg3tValueOf: fileHandle. file = nil ifTrue: [^0]. aNumber < 0 ifTrue: [interpreterProxy success: false. ^nil]. aNumber >= (self cCode: 'result = mpeg3_total_astreams(file)') ifTrue: [ interpreterProxy success: false. ^0 ]. arrayBase _ self cCoerce: anArray to: 'short *'. interpreterProxy failed ifTrue: [^nil]. self cCode: 'result = mpeg3_read_audio(file,(float *) NULL,arrayBase,aChannelNumber,aSampleNumber,aNumber)'. ^result asSmallIntegerObj ! ! !Mpeg3Plugin methodsFor: 'primitives' stamp: 'ls 11/4/2000 14:02'! primitiveMPEG3ReadFrame: fileHandle buffer: aBuffer x: xNumber y: yNumber w: width h: height ow: outWidth oh: outHeight colorModel: model stream: aNumber bytesPerRow: aByteNumber | file result outputRowsPtr bufferBaseAddr | "int mpeg3_read_frame(mpeg3_t *file, unsigned char **output_rows, int in_x, int in_y, int in_w, int in_h, int out_w, int out_h, int color_model, int stream)" self primitive: 'primitiveMPEG3ReadFrame' parameters: #(Oop WordArray SmallInteger SmallInteger SmallInteger SmallInteger SmallInteger SmallInteger SmallInteger SmallInteger SmallInteger). self var: #file declareC: 'mpeg3_t * file'. self var: #bufferBaseAddr declareC: 'unsigned char *bufferBaseAddr'. self var: #outputRowsPtr declareC: 'unsigned char ** outputRowsPtr'. file _ self mpeg3tValueOf: fileHandle. file = nil ifTrue: [^0]. aNumber < 0 ifTrue: [ interpreterProxy success: false. ^nil ]. aNumber >= (self cCode: 'result = mpeg3_total_vstreams(file)') ifTrue: [ interpreterProxy success: false. ^0 ]. bufferBaseAddr _ self cCoerce: aBuffer to: 'unsigned char *'. self cCode: 'outputRowsPtr = (unsigned char **) memoryAllocate(1,sizeof(unsigned char*) * outHeight)'. 0 to: outHeight-1 do: [:i | outputRowsPtr at: i put: (bufferBaseAddr + (aByteNumber*i))]. self cCode: 'result = mpeg3_read_frame(file,outputRowsPtr,xNumber,yNumber,width,height,outWidth,outHeight,model,aNumber)'. self cCode: 'memoryFree(outputRowsPtr)'. ^result asSmallIntegerObj ! ! !Mpeg3Plugin methodsFor: 'primitives' stamp: 'ls 11/4/2000 14:02'! primitiveMPEG3SampleRate: fileHandle stream: aNumber | file result | "int mpeg3_sample_rate(mpeg3_t *file,int stream)" self var: #file declareC: 'mpeg3_t * file'. self primitive: 'primitiveMPEG3SampleRate' parameters: #(Oop SmallInteger). file _ self mpeg3tValueOf: fileHandle. file = nil ifTrue: [^0]. aNumber < 0 ifTrue: [interpreterProxy success: false. ^nil]. aNumber >= (self cCode: 'result = mpeg3_total_astreams(file)') ifTrue: [ interpreterProxy success: false. ^0 ]. self cCode: 'result = mpeg3_sample_rate(file,aNumber)'. ^result asSmallIntegerObj ! ! !Mpeg3Plugin methodsFor: 'primitives' stamp: 'JMM 9/18/2000 00:49'! primitiveMPEG3SeekPercentage: fileHandle percentage: aNumber | file result | "int mpeg3_seek_percentage(mpeg3_t *file, double percentage)" self var: #file declareC: 'mpeg3_t * file'. self primitive: 'primitiveMPEG3SeekPercentage' parameters: #(Oop Float). file _ self mpeg3tValueOf: fileHandle. aNumber < 0.0 ifTrue: [interpreterProxy success: false. ^nil]. aNumber > 1.0 ifTrue: [interpreterProxy success: false. ^nil]. file = nil ifTrue: [^nil]. self cCode: 'result = mpeg3_seek_percentage(file,aNumber)'. ^result asSmallIntegerObj ! ! !Mpeg3Plugin methodsFor: 'primitives' stamp: 'JMM 9/18/2000 00:49'! primitiveMPEG3SetCpus: fileHandle number: cpus | file | "int mpeg3_set_cpus(mpeg3_t *file, int cpus)" self var: #file declareC: 'mpeg3_t * file'. self primitive: 'primitiveMPEG3SetCpus' parameters: #(Oop SmallInteger). file _ self mpeg3tValueOf: fileHandle. cpus < 0 ifTrue: [interpreterProxy success: false. ^nil]. file = nil ifTrue: [^nil]. self cCode: 'mpeg3_set_cpus(file,cpus)'. ! ! !Mpeg3Plugin methodsFor: 'primitives' stamp: 'ls 11/4/2000 14:02'! primitiveMPEG3SetFrame: fileHandle frame: aFrameNumber stream: aNumber | file result | "int mpeg3_set_frame(mpeg3_t *file, long frame, int stream)" self var: #file declareC: 'mpeg3_t * file'. self primitive: 'primitiveMPEG3SetFrame' parameters: #(Oop Float SmallInteger). file _ self mpeg3tValueOf: fileHandle. file = nil ifTrue: [^0]. aNumber < 0 ifTrue: [interpreterProxy success: false. ^nil]. aNumber >= (self cCode: 'result = mpeg3_total_vstreams(file)') ifTrue: [ interpreterProxy success: false. ^0 ]. self cCode: 'result = mpeg3_set_frame(file,(long) aFrameNumber,aNumber)'. ^result asSmallIntegerObj ! ! !Mpeg3Plugin methodsFor: 'primitives' stamp: 'JMM 9/18/2000 00:49'! primitiveMPEG3SetMmx: fileHandle useMmx: mmx | file | "int mpeg3_set_mmx(mpeg3_t *file, int use_mmx)" self var: #file declareC: 'mpeg3_t * file'. self primitive: 'primitiveMPEG3SetMmx' parameters: #(Oop Boolean). file _ self mpeg3tValueOf: fileHandle. file = nil ifTrue: [^nil]. self cCode: 'mpeg3_set_mmx(file,mmx)'. ! ! !Mpeg3Plugin methodsFor: 'primitives' stamp: 'ls 11/4/2000 14:03'! primitiveMPEG3SetSample: fileHandle sample: aSampleNumber stream: aNumber | file result | "int mpeg3_set_sample(mpeg3_t *file, long sample, int stream)" self var: #file declareC: 'mpeg3_t * file'. self primitive: 'primitiveMPEG3SetSample' parameters: #(Oop Float SmallInteger). file _ self mpeg3tValueOf: fileHandle. file = nil ifTrue: [^0]. aNumber < 0 ifTrue: [interpreterProxy success: false. ^nil]. aNumber >= (self cCode: 'result = mpeg3_total_astreams(file)') ifTrue: [ interpreterProxy success: false. ^0 ]. aSampleNumber < 0 ifTrue: [interpreterProxy success: false. ^nil]. self cCode: 'result = mpeg3_set_sample(file,aSampleNumber,aNumber)'. ^result asSmallIntegerObj ! ! !Mpeg3Plugin methodsFor: 'primitives' stamp: 'JMM 9/18/2000 01:45'! primitiveMPEG3TellPercentage: fileHandle | file result | "double mpeg3_tell_percentage(mpeg3_t *file)" self var: # result declareC: 'double result'. self var: #file declareC: 'mpeg3_t * file'. self primitive: 'primitiveMPEG3TellPercentage' parameters: #(Oop). file _ self mpeg3tValueOf: fileHandle. file = nil ifTrue: [^nil]. self cCode: 'result = mpeg3_tell_percentage(file)'. ^result asOop: Float. ! ! !Mpeg3Plugin methodsFor: 'primitives' stamp: 'JMM 9/18/2000 00:49'! primitiveMPEG3TotalAStreams: fileHandle | file result | "int mpeg3_total_astreams(mpeg3_t *file)" self var: #file declareC: 'mpeg3_t * file'. self primitive: 'primitiveMPEG3TotalAStreams' parameters: #(Oop). file _ self mpeg3tValueOf: fileHandle. file = nil ifTrue: [^0]. self cCode: 'result = mpeg3_total_astreams(file)'. ^result asSmallIntegerObj ! ! !Mpeg3Plugin methodsFor: 'primitives' stamp: 'JMM 9/18/2000 14:34'! primitiveMPEG3TotalVStreams: fileHandle | file result | "int mpeg3_total_vstreams(mpeg3_t *file)" self var: #file declareC: 'mpeg3_t * file'. self primitive: 'primitiveMPEG3TotalVStreams' parameters: #(Oop). file _ self mpeg3tValueOf: fileHandle. file = nil ifTrue: [^nil]. self cCode: 'result = mpeg3_total_vstreams(file)'. ^result asSmallIntegerObj ! ! !Mpeg3Plugin methodsFor: 'primitives' stamp: 'ls 11/4/2000 14:03'! primitiveMPEG3VideoFrames: fileHandle stream: aNumber | file result | "long mpeg3_video_frames(mpeg3_t *file, int stream)" self var: #file declareC: 'mpeg3_t * file'. self primitive: 'primitiveMPEG3VideoFrames' parameters: #(Oop SmallInteger). file _ self mpeg3tValueOf: fileHandle. file = nil ifTrue: [^0]. aNumber < 0 ifTrue: [interpreterProxy success: false. ^nil]. aNumber >= (self cCode: 'result = mpeg3_total_vstreams(file)') ifTrue: [ interpreterProxy success: false. ^0 ]. self cCode: 'result = mpeg3_video_frames(file,aNumber)'. ^result asOop: Float. ! ! !Mpeg3Plugin methodsFor: 'primitives' stamp: 'ls 11/4/2000 14:03'! primitiveMPEG3VideoHeight: fileHandle stream: aNumber | file result | "int mpeg3_video_height(mpeg3_t *file,int stream)" self var: #file declareC: 'mpeg3_t * file'. self primitive: 'primitiveMPEG3VideoHeight' parameters: #(Oop SmallInteger). file _ self mpeg3tValueOf: fileHandle. file = nil ifTrue: [^0]. aNumber < 0 ifTrue: [interpreterProxy success: false. ^nil]. aNumber >= (self cCode: 'result = mpeg3_total_vstreams(file)') ifTrue: [ interpreterProxy success: false. ^0 ]. self cCode: 'result = mpeg3_video_height(file,aNumber)'. ^result asSmallIntegerObj ! ! !Mpeg3Plugin methodsFor: 'primitives' stamp: 'ls 11/4/2000 14:04'! primitiveMPEG3VideoWidth: fileHandle stream: aNumber | file result | "int mpeg3_video_width(mpeg3_t *file, int stream)" self var: #file declareC: 'mpeg3_t * file'. self primitive: 'primitiveMPEG3VideoWidth' parameters: #(Oop SmallInteger). file _ self mpeg3tValueOf: fileHandle. file = nil ifTrue: [^0]. aNumber < 0 ifTrue: [interpreterProxy success: false. ^nil]. aNumber >= (self cCode: 'result = mpeg3_total_vstreams(file)') ifTrue: [ interpreterProxy success: false. ^0 ]. self cCode: 'result = mpeg3_video_width(file,aNumber)'. ^result asSmallIntegerObj ! ! !Mpeg3Plugin class methodsFor: 'initialize-release' stamp: 'JMM 10/2/2000 12:56'! declareCVarsIn: cg super declareCVarsIn: cg. cg var: 'mpegFiles' declareC: 'mpeg3_t *mpegFiles[1024+1]'. ! ! !Mpeg3Plugin class methodsFor: 'initialize-release' stamp: 'JMM 10/2/2000 12:53'! headerFile ^' #include "changesForSqueak.h" #include "libmpeg3.h"'! ! MPEGPlayer removeSelector: #currentAudioSample! MPEGPlayer removeSelector: #currentAudioSample:! MPEGPlayer removeSelector: #currentLocationInPercent! MPEGPlayer removeSelector: #currentVideoFrame! MPEGPlayer removeSelector: #currentVideoFrame:! MPEGPlayer removeSelector: #setAudioLocation:forStream:! MPEGPlayer removeSelector: #setVideoLocation:forStream:! !MPEGPlayer reorganize! ('access' audioPlayerProcess audioPlayerProcess: clockBias clockBias: clockBiasForStream: clockBiasForStream:put: currentAudioSampleForStream: currentAudioSampleForStream:put: currentVideoFrameForStream: currentVideoFrameForStream:put: errorForSoundStart: external fileName form form: frameRate frameRate: lastDelay lastDelay: morph morph: mpegFile noSound noSound: playerProcessPriority playerProcessPriority: sampleRate sampleRate: soundQueue soundQueue: startTime startTime: startTimeForStream: startTimeForStream:put: timeCheck timeCheck: videoPlayerProcess videoPlayerProcess: volume:) ('access to attributes' audioChannels: audioSampleRate: audioSamples: currentExternalLocationInPercent currentLocationInPercent: endOfAudio: endOfVideo: getTOC:doStreams: getTimeCode hasAudio hasVideo setMMX: totalVideoStreams videoDropFrames:stream: videoFrameHeight: videoFrameRate: videoFrameWidth: videoFrames: videoPreviousFrame: videoSetCPUs:) ('audio' createSoundFrom: privatePlayAudioStream: readSoundChannel:stream: setupStream: setupStreamNoSeek: startAudioPlayerProcess: updateSoundStream:) ('delay' calculateDelayGivenFrame:stream: calculateDelayToSoundGivenFrame:stream: decideToSkipAFrame:averageWait:stream:) ('initialize-release' close initialize: initializeWithFileName: initializeWithFileName:form: initializeWithFileName:morph: stopAndClose) ('play' playAudioStream: playAudioStreamNoSeek: playAudioStreamWaitTilDone: playStream: playStreamWaitTilDone: playVideoStream: playVideoStreamWaitTilDone:) ('play controls' backAudio:forStream: backVideo:forStream: forwardAudio:forStream: forwardVideo:forStream: isPlaying recalculateNewSampleLocationForStream:givenFrame: seekToHere:forStream: seekVideoAudioBasedOnFrame:forStream: setLocation:forStream: stop) ('utility' changed checkForm:) ('video' privatePlayVideoStream: startVideoPlayerProcess: videoLoop:) !