TheorafileGMS/gamemaker/TheorafileGMS/scripts/TheorafileGMS_Scripts/TheorafileGMS_Scripts.gml

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;
}
}
}
}