Movie player cleanup and additional comments
git-svn-id: svn://svn.code.sf.net/p/sc2/code/trunk@1259 8092fc87-c524-0410-9efc-e669fe64eaf9
This commit is contained in:
@@ -28,9 +28,13 @@ InitVideo (BOOLEAN useCDROM)
|
|||||||
//useCDROM doesn't really apply to us
|
//useCDROM doesn't really apply to us
|
||||||
{
|
{
|
||||||
TFB_VideoFormat fmt;
|
TFB_VideoFormat fmt;
|
||||||
|
|
||||||
TFB_GetScreenFormat (&fmt);
|
TFB_GetScreenFormat (&fmt);
|
||||||
return VideoDecoder_Init (0, fmt.BitsPerPixel, fmt.Rmask,
|
if (!VideoDecoder_Init (0, fmt.BitsPerPixel, fmt.Rmask,
|
||||||
fmt.Gmask, fmt.Bmask, fmt.Amask);
|
fmt.Gmask, fmt.Bmask, fmt.Amask))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
return TFB_InitVideoPlayer ();
|
||||||
|
|
||||||
(void)useCDROM; /* dodge compiler warning */
|
(void)useCDROM; /* dodge compiler warning */
|
||||||
}
|
}
|
||||||
@@ -38,6 +42,7 @@ InitVideo (BOOLEAN useCDROM)
|
|||||||
void
|
void
|
||||||
UninitVideo ()
|
UninitVideo ()
|
||||||
{
|
{
|
||||||
|
TFB_UninitVideoPlayer ();
|
||||||
VideoDecoder_Uninit ();
|
VideoDecoder_Uninit ();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -128,7 +133,6 @@ _init_video_file(PVOID pStr)
|
|||||||
vid->w = vid->decoder->w;
|
vid->w = vid->decoder->w;
|
||||||
vid->h = vid->decoder->h;
|
vid->h = vid->decoder->h;
|
||||||
vid->guard = CreateMutex ("video guard", SYNC_CLASS_VIDEO);
|
vid->guard = CreateMutex ("video guard", SYNC_CLASS_VIDEO);
|
||||||
vid->frame_lock = CreateCondVar ("frame lock", SYNC_CLASS_VIDEO);
|
|
||||||
|
|
||||||
return (VIDEO_REF) vid;
|
return (VIDEO_REF) vid;
|
||||||
}
|
}
|
||||||
@@ -143,7 +147,6 @@ DestroyVideo (VIDEO_REF VideoRef)
|
|||||||
|
|
||||||
VideoDecoder_Free (vid->decoder);
|
VideoDecoder_Free (vid->decoder);
|
||||||
DestroyMutex (vid->guard);
|
DestroyMutex (vid->guard);
|
||||||
DestroyCondVar (vid->frame_lock);
|
|
||||||
HFree (vid);
|
HFree (vid);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|||||||
@@ -30,20 +30,20 @@ typedef struct tfb_videoclip
|
|||||||
TFB_VideoDecoder *decoder; // decoder to read from
|
TFB_VideoDecoder *decoder; // decoder to read from
|
||||||
float length; // total length of clip seconds
|
float length; // total length of clip seconds
|
||||||
uint32 w, h;
|
uint32 w, h;
|
||||||
RECT dst_rect; // destination screen rect
|
|
||||||
RECT src_rect; // source rect
|
|
||||||
|
|
||||||
|
// video player data
|
||||||
|
RECT dst_rect; // destination screen rect
|
||||||
|
RECT src_rect; // source rect
|
||||||
MUSIC_REF hAudio;
|
MUSIC_REF hAudio;
|
||||||
Task play_task;
|
Task play_task;
|
||||||
uint32 frame_time; // time when next frame should be rendered
|
uint32 frame_time; // time when next frame should be rendered
|
||||||
TFB_Image* frame;
|
TFB_Image* frame; // frame preped and optimized for rendering
|
||||||
uint32 cur_frame;
|
uint32 cur_frame; // index of frame currently displayed
|
||||||
uint32 max_frame_wait;
|
uint32 max_frame_wait;
|
||||||
bool playing;
|
bool playing;
|
||||||
|
|
||||||
Mutex guard;
|
Mutex guard;
|
||||||
CondVar frame_lock;
|
uint32 want_frame; // audio-signaled desired frame index
|
||||||
uint32 want_frame;
|
|
||||||
|
|
||||||
void* data; // user-defined data
|
void* data; // user-defined data
|
||||||
|
|
||||||
|
|||||||
@@ -58,6 +58,21 @@ typedef struct
|
|||||||
|
|
||||||
} VIDEO_INPUT_STATE;
|
} VIDEO_INPUT_STATE;
|
||||||
|
|
||||||
|
bool
|
||||||
|
TFB_InitVideoPlayer ()
|
||||||
|
{
|
||||||
|
// creation probably needs better handling
|
||||||
|
vp_interthread_lock = CreateSemaphore (1, "inter-thread param lock",
|
||||||
|
SYNC_CLASS_VIDEO);
|
||||||
|
return vp_interthread_lock != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
TFB_UninitVideoPlayer ()
|
||||||
|
{
|
||||||
|
DestroySemaphore (vp_interthread_lock);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
TFB_FadeClearScreen ()
|
TFB_FadeClearScreen ()
|
||||||
{
|
{
|
||||||
@@ -81,8 +96,10 @@ TFB_FadeClearScreen ()
|
|||||||
XFormColorMap ((COLORMAPPTR) xform_buf, 0);
|
XFormColorMap ((COLORMAPPTR) xform_buf, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// audio-synced video playback task
|
||||||
|
// the frame rate and timing is dictated by the audio
|
||||||
int
|
int
|
||||||
ac_video_play_task (void* data)
|
as_video_play_task (void* data)
|
||||||
{
|
{
|
||||||
Task task = (Task) data;
|
Task task = (Task) data;
|
||||||
volatile TFB_VideoClip* vid;
|
volatile TFB_VideoClip* vid;
|
||||||
@@ -104,6 +121,23 @@ ac_video_play_task (void* data)
|
|||||||
|
|
||||||
clagged = 0;
|
clagged = 0;
|
||||||
|
|
||||||
|
// this works like so (audio-synced):
|
||||||
|
// 1. you call VideoDecoder_Seek() [when necessary] and
|
||||||
|
// VideoDecoder_Decode()
|
||||||
|
// 2. wait till the audio signals it's time for this frame
|
||||||
|
// or the maximum inter-frame timeout elapses; the timeout
|
||||||
|
// is necessary because the audio signaling is not precise
|
||||||
|
// (see vp_AudioStart, vp_AudioEnd, vp_BufferTag)
|
||||||
|
// 3. output the frame; if the timeout elapsed, increment the
|
||||||
|
// the lag counter
|
||||||
|
// 4. set the next frame timeout; lag counter increases the
|
||||||
|
// timeout to allow audio to catch up
|
||||||
|
// 5. on a seek operation, the audio stream is moved to the
|
||||||
|
// correct position and then the audio signals the frame
|
||||||
|
// that should be rendered
|
||||||
|
// The system of timeouts and lag counts should make the video
|
||||||
|
// *relatively* smooth
|
||||||
|
//
|
||||||
ret = VideoDecoder_Decode (vid->decoder);
|
ret = VideoDecoder_Decode (vid->decoder);
|
||||||
TimeOut = GetTimeCounter () + vid->decoder->max_frame_wait *
|
TimeOut = GetTimeCounter () + vid->decoder->max_frame_wait *
|
||||||
ONE_SECOND / 1000;
|
ONE_SECOND / 1000;
|
||||||
@@ -175,6 +209,8 @@ ac_video_play_task (void* data)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// audio-independent video playback task
|
||||||
|
// the frame rate and timing is dictated by the video decoder
|
||||||
int
|
int
|
||||||
video_play_task (void* data)
|
video_play_task (void* data)
|
||||||
{
|
{
|
||||||
@@ -281,29 +317,30 @@ TFB_PlayVideo (VIDEO_REF VidRef, uint32 x, uint32 y)
|
|||||||
|
|
||||||
if (!vid->hAudio)
|
if (!vid->hAudio)
|
||||||
{
|
{
|
||||||
fprintf (stderr, "TFB_PlayVideo: Cannot load sound-track for audio-synced video\n");
|
fprintf (stderr, "TFB_PlayVideo: "
|
||||||
|
"Cannot load sound-track for audio-synced video\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// nasty hack for now
|
// nasty hack for now
|
||||||
LockMusicData (vid->hAudio, &pmus);
|
LockMusicData (vid->hAudio, &pmus);
|
||||||
(*pmus)->buffer_tag = HCalloc (sizeof (TFB_SoundTag) * (*pmus)->num_buffers);
|
(*pmus)->buffer_tag = HCalloc (
|
||||||
|
sizeof (TFB_SoundTag) * (*pmus)->num_buffers);
|
||||||
(*pmus)->callbacks = vp_AudioCBs;
|
(*pmus)->callbacks = vp_AudioCBs;
|
||||||
(*pmus)->data = vid; // hijack data ;)
|
(*pmus)->data = vid; // hijack data ;)
|
||||||
UnlockMusicData (vid->hAudio);
|
UnlockMusicData (vid->hAudio);
|
||||||
}
|
}
|
||||||
|
|
||||||
// creation probably needs better handling
|
|
||||||
if (!vp_interthread_lock)
|
|
||||||
vp_interthread_lock = CreateSemaphore (1, "inter-thread param lock", SYNC_CLASS_VIDEO);
|
|
||||||
SetSemaphore (vp_interthread_lock);
|
SetSemaphore (vp_interthread_lock);
|
||||||
vp_interthread_clip = vid;
|
vp_interthread_clip = vid;
|
||||||
|
|
||||||
vid->playing = true;
|
vid->playing = true;
|
||||||
if (vid->decoder->audio_synced)
|
if (vid->decoder->audio_synced)
|
||||||
vid->play_task = AssignTask (ac_video_play_task, 4096, "a/c video player");
|
vid->play_task = AssignTask (
|
||||||
|
as_video_play_task, 4096, "a/s video player");
|
||||||
else
|
else
|
||||||
vid->play_task = AssignTask (video_play_task, 4096, "video player");
|
vid->play_task = AssignTask (
|
||||||
|
video_play_task, 4096, "video player");
|
||||||
|
|
||||||
if (!vid->play_task)
|
if (!vid->play_task)
|
||||||
{
|
{
|
||||||
@@ -392,7 +429,7 @@ TFB_DoVideoInput (PVOID pIS)
|
|||||||
|
|
||||||
TaskSwitch ();
|
TaskSwitch ();
|
||||||
}
|
}
|
||||||
// non a/c decoder seeking is not supported yet
|
// non a/s decoder seeking is not supported yet
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|||||||
@@ -19,6 +19,8 @@
|
|||||||
|
|
||||||
#include "video.h"
|
#include "video.h"
|
||||||
|
|
||||||
|
bool TFB_InitVideoPlayer (void);
|
||||||
|
void TFB_UninitVideoPlayer (void);
|
||||||
void TFB_FadeClearScreen ();
|
void TFB_FadeClearScreen ();
|
||||||
bool TFB_PlayVideo (VIDEO_REF VidRef, uint32 x, uint32 y);
|
bool TFB_PlayVideo (VIDEO_REF VidRef, uint32 x, uint32 y);
|
||||||
void TFB_StopVideo (VIDEO_REF VidRef);
|
void TFB_StopVideo (VIDEO_REF VidRef);
|
||||||
|
|||||||
Reference in New Issue
Block a user