mirror of
https://gitlab.com/Nanolx/qwad.git
synced 2024-11-25 03:56:55 +01:00
182 lines
5.9 KiB
Python
182 lines
5.9 KiB
Python
|
from Struct import *
|
||
|
from pyglet import clock, window, image
|
||
|
from pyglet.gl import *
|
||
|
import cStringIO
|
||
|
import math
|
||
|
|
||
|
from time import time
|
||
|
|
||
|
|
||
|
class THP():
|
||
|
class THPHeader(Struct):
|
||
|
__endian__ = Struct.BE
|
||
|
def __format__(self):
|
||
|
self.magic = Struct.string(4)
|
||
|
self.version = Struct.uint32
|
||
|
self.bufSize = Struct.uint32
|
||
|
self.audioMaxSamples = Struct.uint32
|
||
|
self.frameRate = Struct.float
|
||
|
self.numFrames = Struct.uint32
|
||
|
self.firstFrameSize = Struct.uint32
|
||
|
self.movieDataSize = Struct.uint32
|
||
|
self.compInfoDataOffsets = Struct.uint32
|
||
|
self.offsetDataOffsets = Struct.uint32 #Offset to a offset table, containing offsets to each frame, this allows for starting playback from any frame. If this is 0 then it does not exist.
|
||
|
self.movieDataOffsets = Struct.uint32
|
||
|
self.finalFrameDataOffsets = Struct.uint32
|
||
|
def __str__(self):
|
||
|
ret = "\n"
|
||
|
ret += "Magic: %s\n" % self.magic
|
||
|
ret += "Version: %d.%d.%d\n" % (((self.version & 0xFFFF0000) >> 16), ((self.version & 0xFF00) >> 8), ((self.version & 0xFF)))
|
||
|
ret += "bufSize: %s\n" % self.bufSize
|
||
|
ret += "audioMaxSamples: %d\n" % self.audioMaxSamples
|
||
|
ret += "frameRate: %f\n" % self.frameRate
|
||
|
ret += "numFrames: %d\n" % self.numFrames
|
||
|
ret += "firstFrameSize: %d\n" % self.firstFrameSize
|
||
|
ret += "movieDataSize: %d\n" % self.movieDataSize
|
||
|
ret += "compInfoDataOffsets: 0x%08X\n" % self.compInfoDataOffsets
|
||
|
ret += "offsetDataOffsets: 0x%08X\n" % self.offsetDataOffsets
|
||
|
ret += "movieDataOffsets: 0x%08X\n" % self.movieDataOffsets
|
||
|
ret += "finalFrameDataOffsets: 0x%08X\n" % self.finalFrameDataOffsets
|
||
|
return ret
|
||
|
class THPFrameCompInfo(Struct):
|
||
|
__endian__ = Struct.BE
|
||
|
def __format__(self):
|
||
|
self.numComponents = Struct.uint32
|
||
|
self.frameComp = Struct.uint8[16]
|
||
|
def __str__(self):
|
||
|
ret = ""
|
||
|
ret += "Number of Components: %d\n" % self.numComponents
|
||
|
return ret
|
||
|
class THPCompVideoInfo(Struct):
|
||
|
__endian__ = Struct.BE
|
||
|
def __format__(self):
|
||
|
self.width = Struct.uint32
|
||
|
self.height = Struct.uint32
|
||
|
self.videoType = Struct.uint32
|
||
|
def __str__(self):
|
||
|
tempType = ("Non-Interlaced", "Interlaced", "Odd Interlace", "3", "Even Interlace")
|
||
|
ret = ""
|
||
|
ret += "Width: %d\n" % self.width
|
||
|
ret += "Height: %d\n" % self.height
|
||
|
ret += "VideoType: %s\n" % tempType[self.videoType]
|
||
|
return ret
|
||
|
class THPCompAudioInfo(Struct):
|
||
|
__endian__ = Struct.BE
|
||
|
def __format__(self):
|
||
|
self.sndChannels = Struct.uint32
|
||
|
self.sndFrequency = Struct.uint32
|
||
|
self.sndNumberSamples = Struct.uint32
|
||
|
self.sndNumberTracks = Struct.uint32
|
||
|
def __str__(self):
|
||
|
ret = ""
|
||
|
ret += "Channels: %d\n" % self.sndChannels
|
||
|
ret += "Frequency: %d\n" % self.sndFrequency
|
||
|
ret += "Samples: %d\n" % self.sndNumberSamples
|
||
|
ret += "Tracks: %d\n" % self.sndNumberTracks
|
||
|
return ret
|
||
|
class THPFrameHeader(Struct):
|
||
|
__endian__ = Struct.BE
|
||
|
def __format__(self):
|
||
|
self.frameSizeNext = Struct.uint32
|
||
|
self.frameSizePrev = Struct.uint32
|
||
|
self.vidFileSize = Struct.uint32
|
||
|
self.sndFileSize = Struct.uint32
|
||
|
def __str__(self):
|
||
|
ret = ""
|
||
|
ret += "next Frame Size: %d\n" % self.frameSizeNext
|
||
|
ret += "previous Frame Size: %d\n" % self.frameSizePrev
|
||
|
ret += "Video frame data size: %d\n" % self.vidFileSize
|
||
|
ret += "Track file size: %d\n" % self.sndFileSize
|
||
|
return ret
|
||
|
def readData(self, fp, i=0):
|
||
|
self.frameImage = fp.read(self.vidFileSize)
|
||
|
#fileName = "frame%06d.jpg" % i
|
||
|
#open("out/" + fileName, 'w+b').write(self.frameImage)
|
||
|
#print "Frame: %d" % i
|
||
|
startTime = time()
|
||
|
start = self.frameImage.find('\xff\xda')
|
||
|
end = self.frameImage.rfind('\xff\xd9')
|
||
|
#print "find(%d): This took "%i, time()-startTime,start,end
|
||
|
startTime = time()
|
||
|
startStr = self.frameImage[:start+2]
|
||
|
endStr = self.frameImage[end:]
|
||
|
#print "extr(%d): This took "%i, time()-startTime
|
||
|
self.frameImage = self.frameImage[start+2:end]
|
||
|
self.frameImage = startStr + self.frameImage.replace('\xff','\xff\x00') + endStr
|
||
|
#print self.frameImage
|
||
|
|
||
|
|
||
|
return cStringIO.StringIO(self.frameImage)
|
||
|
def __init__(self, movieFile=None):
|
||
|
if(movieFile==None):
|
||
|
print "Usage: python thp.py filename.thp"
|
||
|
exit(-1)
|
||
|
fp = file(movieFile, 'rb')
|
||
|
HEADER = self.THPHeader()
|
||
|
HEADER.unpack(fp.read(len(HEADER)))
|
||
|
print HEADER
|
||
|
fp.seek(HEADER.compInfoDataOffsets)
|
||
|
CompInfo = self.THPFrameCompInfo()
|
||
|
CompInfo.unpack(fp.read(len(CompInfo)))
|
||
|
print CompInfo
|
||
|
for i in range(0, CompInfo.numComponents):
|
||
|
if(CompInfo.frameComp[i] == 0):
|
||
|
VideoInfo = self.THPCompVideoInfo()
|
||
|
VideoInfo.unpack(fp.read(len(VideoInfo)))
|
||
|
print VideoInfo
|
||
|
if(CompInfo.frameComp[i] == 1):
|
||
|
AudioInfo = self.THPCompAudioInfo()
|
||
|
AudioInfo.unpack(fp.read(len(AudioInfo)))
|
||
|
print AudioInfo
|
||
|
|
||
|
clock.set_fps_limit(HEADER.frameRate)
|
||
|
currOff = HEADER.movieDataOffsets
|
||
|
currSize = HEADER.firstFrameSize
|
||
|
fp.seek(currOff)
|
||
|
|
||
|
win = window.Window(VideoInfo.width, VideoInfo.height)
|
||
|
fps_display = clock.ClockDisplay()
|
||
|
i = 1
|
||
|
j = 1
|
||
|
image_index = 0
|
||
|
image_period = 1.0 / HEADER.frameRate # Reciprocal of the frame rate
|
||
|
remained = 0
|
||
|
|
||
|
while not win.has_exit:
|
||
|
|
||
|
win.dispatch_events()
|
||
|
win.clear()
|
||
|
|
||
|
dt = clock.tick()
|
||
|
|
||
|
skip = math.floor((dt+remained)/image_period)
|
||
|
j += skip
|
||
|
print skip, ":break:", i, j, skip
|
||
|
remained = dt - skip * image_period
|
||
|
|
||
|
tempFrame = self.THPFrameHeader()
|
||
|
tempFrame.unpack(fp.read(len(tempFrame)))
|
||
|
|
||
|
for xx in range(1,skip):
|
||
|
currOff = currOff+currSize
|
||
|
currSize = tempFrame.frameSizeNext
|
||
|
fp.seek(currOff)
|
||
|
tempFrame = self.THPFrameHeader()
|
||
|
tempFrame.unpack(fp.read(len(tempFrame)))
|
||
|
|
||
|
imagedat = tempFrame.readData(fp, i)
|
||
|
|
||
|
pic = image.load("image.jpg",imagedat)
|
||
|
pic.blit(0,0)
|
||
|
|
||
|
currOff = currOff+currSize
|
||
|
currSize = tempFrame.frameSizeNext
|
||
|
fp.seek(currOff)
|
||
|
|
||
|
|
||
|
fps_display.draw()
|
||
|
win.flip()
|
||
|
i += 1
|
||
|
|
||
|
if __name__=='__main__':
|
||
|
THP(*sys.argv[1:])
|