CRI Sofdec2  Last Updated: 2022-11-21 16:25 p
Sample: Simple Playback

To simplify the implementation of this sample program, the following methods are used for playback.

  • Memory function registration (individual work buffers are not passed)
  • No memory functions for metadata (no seek playback or cuepoint acquisition)
  • No header pre-analysis (fixed movie resolution and alpha channel existence)

Important sections of the sample code will be examined in detail and explained in a number of steps.

1. Initialization and Handle Creation
/* Register memory allocator to Sofdec2 */
criMana_SetUserAllocator(user_alloc, user_free, NULL);
/* CRI AtomEx library initialization (must be performed before Mana initialization) */
criAtomEx_Initialize(NULL, NULL, 0);
/* CRI Mana library initialization (multithreaded model by default) */
criMana_Initialize(NULL, NULL, 0);
/* Player creation */
app_obj->player = criManaPlayer_Create(NULL, 0);
void criMana_Initialize(const CriManaLibConfig *config, void *work, CriSint32 work_size)
Library initialization.
void criMana_SetUserAllocator(CriManaMallocFunc malloc_func, CriManaFreeFunc free_func, void *obj)
Register user allocator.
CriManaPlayerHn criManaPlayer_Create(void *work, CriSint32 work_size)
Create Mana player (no config specified)
By registering a memory allocator in advance with the criMana_SetUserAllocator function, you can omit work area specification when initializing modules or creating handles that require a work area. Note that you must call the ::criAtomEx_Initialize function even when using only Sofdec2 alone.



2. Start Playback
/* Movie file specification */
criManaPlayer_SetFile(app_obj->player, NULL, USM_FILE);
/* Start playback */
criManaPlayer_Start(app_obj->player);
void criManaPlayer_Start(CriManaPlayerHn player)
Start playback.
void criManaPlayer_SetFile(CriManaPlayerHn player, CriFsBinderHn bndrhn, const CriChar8 *path)
Set movie file.
If a memory allocator has been registered, you can omit the work buffer settings for playback and begin playback immediately via the criManaPlayer_SetPlaybackWork function.



3. Regular Processing
/* [Regular Processing] Execute Atom server processing */
criAtomEx_ExecuteMain();
/* [Regular Processing] Movie time synchronization */
/* [Regular Processing] Execute server processing */
void criMana_SyncMasterTimer(void)
Synchronize with the master timer.
void criMana_ExecuteMain(void)
Execute server processing.
Call the above three functions in the application loop every V. If these functions are not called once for more than one v-sync, the movie playback may stutter.



4. Getting Video Frames
/* Are there any decoded frames in the frame pool? */
if (criManaPlayer_ReferFrame(app_obj->player, &frame_info) == CRI_TRUE) {
/* Is the frame on time for display? */
if (criManaPlayer_IsFrameOnTime(app_obj->player, &frame_info) == CRI_TRUE) {
/* Copy frame buffers for shaders */
smpvideo_texture_lock_buffer(app_obj->svt, &yuvbufs);
criManaPlayer_CopyFrameToBuffersYUV(app_obj->player, &frame_info, &yuvbufs);
smpvideo_texture_unlock_buffer(app_obj->svt);
/* Discard the frame because rendering is finished */
criManaPlayer_DiscardFrame(app_obj->player, &frame_info);
}
}
CriBool criManaPlayer_IsFrameOnTime(CriManaPlayerHn player, const CriManaFrameInfo *frame_info)
Determine frame time.
void criManaPlayer_CopyFrameToBuffersYUV(CriManaPlayerHn player, const CriManaFrameInfo *frame_info, CriManaTextureBuffersYUV *frame_buf)
Get decoding results (YUV individual buffer format)
void criManaPlayer_DiscardFrame(CriManaPlayerHn player, const CriManaFrameInfo *frame_info)
Release frame.
CriBool criManaPlayer_ReferFrame(CriManaPlayerHn player, CriManaFrameInfo *frame_info)
Refer to decoded frame information.
YUV texture buffer structure.
Definition: cri_mana.h:904
The library does not perform any rendering, so you must allocate a texture to render the movie in your application. Then, select the correct frame format and copy the data to the texture buffer.


After copying the frame data in the application for the frame referenced via criManaPlayer_ReferFrame function, you must call the criManaPlayer_DiscardFrame function or you will be unable to reference the next frame. Refer toVideo Frame Management for details related to video frame acquisition.



5. Checking for the End of Playback and Playback Stopped Status
/* Get the Mana player status */
app_obj->player_status = criManaPlayer_GetStatus(app_obj->player);
/* If playback is finished or stopped, request finalization for the application */
if (app_obj->player_status == CRIMANAPLAYER_STATUS_PLAYEND ||
app_obj->player_status == CRIMANAPLAYER_STATUS_STOP) {
return CRI_FALSE;
}
CriManaPlayerStatus criManaPlayer_GetStatus(CriManaPlayerHn player)
Get the Mana player status.
@ CRIMANAPLAYER_STATUS_STOP
Definition: cri_mana.h:210
@ CRIMANAPLAYER_STATUS_PLAYEND
Definition: cri_mana.h:216
If the player status returned by the criManaPlayer_GetStatus function is (CRIMANAPLAYER_STATUS_PLAYEND), this means that playback of the movie has ended. If playback has been stopped via the criManaPlayer_Stop function, the playback stopped status ( CRIMANAPLAYER_STATUS_STOP) will be returned. Be sure not to destroy the player handle until this state is returned.



6. Finalization Processing
/* Destroy the player handle */
criManaPlayer_Destroy(app_obj->player);
/* Mana library finalization */
/* AtomEx library finalization */
criAtomEx_Finalize();
void criMana_Finalize(void)
Finalize library.
void criManaPlayer_Destroy(CriManaPlayerHn player)
Destroy the Mana player.
When ending movie playback, destroy each handle via their appropriate functions. Work areas allocated by the library through calls to the registered memory allocator function are freed in the same way through calls to the registered allocator via corresponding destroy/finalize functions.