From 63e22090d265f011ae659641720eca13e68ec250 Mon Sep 17 00:00:00 2001 From: avolkov Date: Tue, 23 Sep 2003 20:25:48 +0000 Subject: [PATCH] Movie player cleanup and additional comments git-svn-id: svn://svn.code.sf.net/p/sc2/code/trunk@1259 8092fc87-c524-0410-9efc-e669fe64eaf9 --- sc2/src/sc2code/libs/video/video.c | 11 ++++-- sc2/src/sc2code/libs/video/video.h | 14 +++---- sc2/src/sc2code/libs/video/vidplayer.c | 55 +++++++++++++++++++++----- sc2/src/sc2code/libs/video/vidplayer.h | 2 + 4 files changed, 62 insertions(+), 20 deletions(-) diff --git a/sc2/src/sc2code/libs/video/video.c b/sc2/src/sc2code/libs/video/video.c index 1bc4b2d03..9f3d68fa2 100644 --- a/sc2/src/sc2code/libs/video/video.c +++ b/sc2/src/sc2code/libs/video/video.c @@ -28,9 +28,13 @@ InitVideo (BOOLEAN useCDROM) //useCDROM doesn't really apply to us { TFB_VideoFormat fmt; + TFB_GetScreenFormat (&fmt); - return VideoDecoder_Init (0, fmt.BitsPerPixel, fmt.Rmask, - fmt.Gmask, fmt.Bmask, fmt.Amask); + if (!VideoDecoder_Init (0, fmt.BitsPerPixel, fmt.Rmask, + fmt.Gmask, fmt.Bmask, fmt.Amask)) + return FALSE; + + return TFB_InitVideoPlayer (); (void)useCDROM; /* dodge compiler warning */ } @@ -38,6 +42,7 @@ InitVideo (BOOLEAN useCDROM) void UninitVideo () { + TFB_UninitVideoPlayer (); VideoDecoder_Uninit (); } @@ -128,7 +133,6 @@ _init_video_file(PVOID pStr) vid->w = vid->decoder->w; vid->h = vid->decoder->h; vid->guard = CreateMutex ("video guard", SYNC_CLASS_VIDEO); - vid->frame_lock = CreateCondVar ("frame lock", SYNC_CLASS_VIDEO); return (VIDEO_REF) vid; } @@ -143,7 +147,6 @@ DestroyVideo (VIDEO_REF VideoRef) VideoDecoder_Free (vid->decoder); DestroyMutex (vid->guard); - DestroyCondVar (vid->frame_lock); HFree (vid); return TRUE; diff --git a/sc2/src/sc2code/libs/video/video.h b/sc2/src/sc2code/libs/video/video.h index d17199628..49a1db98f 100644 --- a/sc2/src/sc2code/libs/video/video.h +++ b/sc2/src/sc2code/libs/video/video.h @@ -30,20 +30,20 @@ typedef struct tfb_videoclip TFB_VideoDecoder *decoder; // decoder to read from float length; // total length of clip seconds 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; Task play_task; uint32 frame_time; // time when next frame should be rendered - TFB_Image* frame; - uint32 cur_frame; + TFB_Image* frame; // frame preped and optimized for rendering + uint32 cur_frame; // index of frame currently displayed uint32 max_frame_wait; bool playing; Mutex guard; - CondVar frame_lock; - uint32 want_frame; + uint32 want_frame; // audio-signaled desired frame index void* data; // user-defined data diff --git a/sc2/src/sc2code/libs/video/vidplayer.c b/sc2/src/sc2code/libs/video/vidplayer.c index c31a85d22..07b3cf4d7 100644 --- a/sc2/src/sc2code/libs/video/vidplayer.c +++ b/sc2/src/sc2code/libs/video/vidplayer.c @@ -58,6 +58,21 @@ typedef struct } 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 TFB_FadeClearScreen () { @@ -81,8 +96,10 @@ TFB_FadeClearScreen () XFormColorMap ((COLORMAPPTR) xform_buf, 0); } +// audio-synced video playback task +// the frame rate and timing is dictated by the audio int -ac_video_play_task (void* data) +as_video_play_task (void* data) { Task task = (Task) data; volatile TFB_VideoClip* vid; @@ -104,6 +121,23 @@ ac_video_play_task (void* data) 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); TimeOut = GetTimeCounter () + vid->decoder->max_frame_wait * ONE_SECOND / 1000; @@ -175,6 +209,8 @@ ac_video_play_task (void* data) return 0; } +// audio-independent video playback task +// the frame rate and timing is dictated by the video decoder int video_play_task (void* data) { @@ -281,29 +317,30 @@ TFB_PlayVideo (VIDEO_REF VidRef, uint32 x, uint32 y) 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; } // nasty hack for now 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)->data = vid; // hijack data ;) 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); vp_interthread_clip = vid; vid->playing = true; 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 - vid->play_task = AssignTask (video_play_task, 4096, "video player"); + vid->play_task = AssignTask ( + video_play_task, 4096, "video player"); if (!vid->play_task) { @@ -392,7 +429,7 @@ TFB_DoVideoInput (PVOID pIS) TaskSwitch (); } - // non a/c decoder seeking is not supported yet + // non a/s decoder seeking is not supported yet } return TRUE; diff --git a/sc2/src/sc2code/libs/video/vidplayer.h b/sc2/src/sc2code/libs/video/vidplayer.h index b02265625..095f55330 100644 --- a/sc2/src/sc2code/libs/video/vidplayer.h +++ b/sc2/src/sc2code/libs/video/vidplayer.h @@ -19,6 +19,8 @@ #include "video.h" +bool TFB_InitVideoPlayer (void); +void TFB_UninitVideoPlayer (void); void TFB_FadeClearScreen (); bool TFB_PlayVideo (VIDEO_REF VidRef, uint32 x, uint32 y); void TFB_StopVideo (VIDEO_REF VidRef);