162 lines
4.2 KiB
Plaintext
162 lines
4.2 KiB
Plaintext
enum Theorafile_VideoState
|
|
{
|
|
Stopped,
|
|
Playing,
|
|
Paused
|
|
}
|
|
|
|
function Theorafile_Open(filename)
|
|
{
|
|
var _handle = ptr(TheorafileGMS_Open(filename));
|
|
show_debug_message("handle: " + string(_handle));
|
|
|
|
var _yWidth = TheorafileGMS_Width(_handle);
|
|
var _yHeight = TheorafileGMS_Height(_handle);
|
|
var _frames_per_second = TheorafileGMS_FPS(_handle);
|
|
var _uvWidth = TheorafileGMS_UVWidth(_handle);
|
|
var _uvHeight = TheorafileGMS_UVHeight(_handle);
|
|
|
|
var _bufferSize = TheorafileGMS_RequiredBufferSizeInBytes(_handle);
|
|
|
|
vertex_format_begin();
|
|
vertex_format_add_position();
|
|
vertex_format_add_texcoord();
|
|
var _vformat = vertex_format_end();
|
|
|
|
var _vbuff = vertex_create_buffer();
|
|
vertex_begin(_vbuff, _vformat);
|
|
vertex_position(_vbuff, -1, 1);
|
|
vertex_texcoord(_vbuff, 0, 0);
|
|
vertex_position(_vbuff, 3, 1);
|
|
vertex_texcoord(_vbuff, 2, 0);
|
|
vertex_position(_vbuff, -1, -3);
|
|
vertex_texcoord(_vbuff, 0, 2);
|
|
vertex_end(_vbuff);
|
|
|
|
return {
|
|
handle: _handle,
|
|
bufferSize: _bufferSize,
|
|
yuvBuffer: buffer_create(_bufferSize, buffer_fixed, 4),
|
|
yWidth: _yWidth,
|
|
yHeight: _yHeight,
|
|
uvWidth: _uvWidth,
|
|
uvHeight: _uvHeight,
|
|
framesPerSecond: _frames_per_second,
|
|
ySurface: surface_create(_yWidth, _yHeight),
|
|
uSurface: surface_create(_uvWidth, _uvHeight),
|
|
vSurface: surface_create(_uvWidth, _uvHeight),
|
|
videoSurface: surface_create(_yWidth, _yHeight),
|
|
elapsed_time: 0,
|
|
currentFrame: 0,
|
|
state: Theorafile_VideoState.Stopped,
|
|
looped: false,
|
|
triangle_buffer: _vbuff,
|
|
triangle_buffer_format: _vformat
|
|
};
|
|
}
|
|
|
|
function Theorafile_Close(video)
|
|
{
|
|
buffer_delete(video.yuvBuffer);
|
|
vertex_format_delete(video.triangle_buffer_format);
|
|
vertex_delete_buffer(video.triangle_buffer);
|
|
TheorafileGMS_Close(video.handle);
|
|
}
|
|
|
|
function Theorafile_Play(video)
|
|
{
|
|
if (video.state == Theorafile_VideoState.Stopped)
|
|
{
|
|
if (video.handle != 0 && TheorafileGMS_HasVideo(video.handle) == 1)
|
|
{
|
|
video.elapsed_time = 0;
|
|
video.state = Theorafile_VideoState.Playing;
|
|
TheorafileGMS_ReadVideo(video.handle, buffer_get_address(video.yuvBuffer), 1);
|
|
}
|
|
}
|
|
}
|
|
|
|
function Theorafile_UpdateTextures(video)
|
|
{
|
|
if (!surface_exists(video.ySurface))
|
|
{
|
|
video.ySurface = surface_create(video.yWidth, video.yHeight);
|
|
}
|
|
|
|
if (!surface_exists(video.uSurface))
|
|
{
|
|
video.uSurface = surface_create(video.uvWidth, video.uvHeight);
|
|
}
|
|
|
|
if (!surface_exists(video.vSurface))
|
|
{
|
|
video.vSurface = surface_create(video.uvWidth, video.uvHeight);
|
|
}
|
|
|
|
var _y_data_length = (video.yWidth * video.yHeight * 4);
|
|
var _uv_data_length = (video.uvWidth * video.uvHeight * 4);
|
|
|
|
buffer_set_surface(video.yuvBuffer, video.ySurface, 0);
|
|
buffer_set_surface(video.yuvBuffer, video.uSurface, _y_data_length);
|
|
buffer_set_surface(video.yuvBuffer, video.vSurface, _y_data_length + _uv_data_length);
|
|
}
|
|
|
|
function Theorafile_UpdateSurface(video)
|
|
{
|
|
if (video.state == Theorafile_VideoState.Playing)
|
|
{
|
|
video.elapsed_time += 1 / room_speed;
|
|
|
|
var _current_frame = video.elapsed_time * video.framesPerSecond;
|
|
|
|
if (floor(_current_frame) > video.currentFrame)
|
|
{
|
|
if TheorafileGMS_ReadVideo(video.handle, buffer_get_address(video.yuvBuffer), 1) == 1
|
|
{
|
|
Theorafile_UpdateTextures(video);
|
|
|
|
if !surface_exists(video.videoSurface)
|
|
{
|
|
video.videoSurface = surface_create(video.yWidth, video.yHeight);
|
|
}
|
|
|
|
surface_set_target(video.videoSurface);
|
|
shader_set(YUVToRGB);
|
|
|
|
ySampler = shader_get_sampler_index(YUVToRGB, "y_tex");
|
|
uSampler = shader_get_sampler_index(YUVToRGB, "u_tex");
|
|
vSampler = shader_get_sampler_index(YUVToRGB, "v_tex");
|
|
texture_set_stage(ySampler, surface_get_texture(video.ySurface));
|
|
texture_set_stage(uSampler, surface_get_texture(video.uSurface));
|
|
texture_set_stage(vSampler, surface_get_texture(video.vSurface));
|
|
|
|
vertex_submit(video.triangle_buffer, pr_trianglelist, -1);
|
|
|
|
shader_reset();
|
|
surface_reset_target();
|
|
}
|
|
|
|
video.currentFrame = floor(_current_frame);
|
|
}
|
|
|
|
var _ended = TheorafileGMS_EndOfStream(video.handle);
|
|
|
|
if (_ended)
|
|
{
|
|
video.elapsed_time = 0;
|
|
video.most_recent_time = 0;
|
|
|
|
TheorafileGMS_Reset(video.handle);
|
|
|
|
if (video.looped)
|
|
{
|
|
video.most_recent_time = get_timer();
|
|
}
|
|
else
|
|
{
|
|
video.state = Theorafile_VideoState.Stopped;
|
|
}
|
|
}
|
|
}
|
|
}
|