CRI Sofdec2  Last Updated: 2022-11-21 16:25 p
Memory Management

This section explains memory management when playing a movie with Sofdec2.
You can also use the memory management system of the application itself. The following will explain how.

Sofdec2 Memory Management (Summary)

Work buffers that require the Sofdec2 library are specified from all applications.
The library does not internally use system functions to allocate memory on its own.

The work buffers passed to the Sofdec2 library are broadly divided into four types.

Types of Work Buffers Needed for the Sofdec2 Library
Types of Work Buffer Description
(a) Common library Passed when the library is initialized. One work buffer for the entire library.
(b) Handle base Passed when a playback handle is created. One work buffer is needed for each handle.
(c) Playback work Size determined by the movie data specs and playback method.
It is passed after playback once the header has been analyzed.
(d) Metadata A buffer to store seek and cuepoint information.
It is passed during header analysis.

(a)(b)(c) use a work size calculation function or a work size get function, and the application allocates and passes the required work buffer.
Only (d) differs in how it allocates work. With (d), the application registers the memory function for the metadata and the library calls that function.


Common Library Work Buffer

A work buffer that will be shared by the library needs to be specified when the library is initialized.
Once the CriManaLibConfig structure is zeroed, you can get the work size from specifying the required parameters with criMana_CalculateLibWorkSize().
The allocated work buffer is specified as an argument of the criMana_Initialize() initialization function.

CriManaLibConfig lib_config;
/* Specify library initialization parameters */
memset(&lib_config, 0, sizeof(lib_config));
lib_config.max_decoder_handles = 1;
/* Initialize Mana library */
lib_work_size = criMana_CalculateLibWorkSize(&lib_config);
lib_work = malloc(lib_work_size);
criMana_Initialize(&lib_config, lib_work, lib_work_size);
void criMana_Initialize(const CriManaLibConfig *config, void *work, CriSint32 work_size)
Library initialization.
CriSint32 criMana_CalculateLibWorkSize(const CriManaLibConfig *config)
Calculate library initialization work area size.
@ CRIMANA_THREAD_MODEL_SINGLE
Definition: cri_mana.h:258
Mana library initialization parameters.
Definition: cri_mana.h:460
CriUint32 max_decoder_handles
Definition: cri_mana.h:461
CriManaThreadModel thread_model
Definition: cri_mana.h:462

Handle Base Work Buffer

You will need to specify the handle base work buffer when creating the CriManaPlayerHn playback handle.
The handle base work buffer is included in the playback handle management domain and the header analysis buffer.
By separating handle creation and the specification of the specs of the movie to play back, you can reuse a playback handle that you used once without wasting memory.

You can get the handle base work buffer size with criManaPlayer_CalculateHanldeWorkSize(). There is no argument.
The allocated work buffer is specified as an argument of the criManaPlayer_Create() handle creator function.

/* Create Mana handle */
hn_work_size = criManaPlayer_CalculateHanldeWorkSize();
hn_work = malloc(hn_work_size);
mana = criManaPlayer_Create(hn_work, hn_work_size);
CriManaPlayerHn criManaPlayer_Create(void *work, CriSint32 work_size)
Create Mana player (no config specified)
CriManaPlayerObj * CriManaPlayerHn
Player handle.
Definition: cri_mana.h:571

Playback Work Buffers

Once you use a playback handle and the movie file header is analyzed, you will need to specify a playback work buffer in order to actually play the movie.
The information needed to calculate the playback work buffer is divided into base structure types and applied structure types.

Playback work buffer parameters
Parameter type Description
Playback work parameter structure (base)
CriManaPlaybackBasicWorkConfig
Parameters for video resolution, playback audio track numbers, read buffer information, and subtitle information.
Playback work parameter structure (applied)
CriManaPlaybackExWorkConfig
Parameters for alpha movies and additional voice tracks. Can be omitted.

You can use criManaPlayer_GetPlaybackWorkParam() to get the parameters for the playback work buffers once the header has been analyzed.
With the parameters gotten by the application, you can adjust just the parameters that you want to change and use them as the criManaPlayer_CalculatePlaybackWorkSize() argument, which is a function for calculating work buffers.

If you know the resolution and audio specs beforehand, then the application can create the playback work buffer parameters directly without analyzing the header.

The following is a sample code for having the application manually create playback work buffer parameters without analyzing the header beforehand.

/* Manually set playback work parameters */
memset(&config_b, 0, sizeof(config_b));
config_b.common_params.readbuf_size_byte = 4*1000*1000/8; /* calculate from bit rate */
config_b.video_params.video_flag = CRI_TRUE;
config_b.video_params.max_width = 320;
config_b.video_params.max_height = 240;
config_b.main_audio_params.audio_flag = CRI_TRUE;
config_b.main_audio_params.sampling_rate = 480000;
/* Calculate and allocate playback work buffer */
ply_work_size = criManaPlayer_CalculatePlaybackWorkSize(mana, &config_b, NULL);
ply_work = malloc(ply_work_size);
criManaPlayer_SetPlaybackWork(mana, &config_b, NULL, ply_work, ply_work_size);
CriSint32 criManaPlayer_CalculatePlaybackWorkSize(CriManaPlayerHn player, const CriManaPlaybackBasicWorkConfig *config_basic, const CriManaPlaybackExWorkConfig *config_ex)
Calculate playback work area size.
void criManaPlayer_SetPlaybackWork(CriManaPlayerHn player, const CriManaPlaybackBasicWorkConfig *config_basic, const CriManaPlaybackExWorkConfig *config_ex, void *work, CriSint32 work_size)
Set playback work area.
CriSint32 output_buffer_samples
Definition: cri_mana.h:631
CriUint32 num_channels
Definition: cri_mana.h:630
CriUint32 sampling_rate
Definition: cri_mana.h:629
CriBool audio_flag
Definition: cri_mana.h:628
Playback work parameter structure (basic)
Definition: cri_mana.h:684
CriManaPlaybackCommonParams common_params
Definition: cri_mana.h:685
CriManaPlaybackAudioParams main_audio_params
Definition: cri_mana.h:687
CriManaPlaybackVideoParams video_params
Definition: cri_mana.h:686
CriSint32 readbuf_size_byte
Definition: cri_mana.h:587
CriBool video_flag
Definition: cri_mana.h:604
CriSint32 max_width
Definition: cri_mana.h:605
CriSint32 max_height
Definition: cri_mana.h:606
CriSint32 num_frame_pools
Definition: cri_mana.h:607

The following is a sample code that gets and specifies playback work buffer parameters after the header has been analyzed.

/* Specify file name and start header analysis */
criManaPlayer_SetFile(mana, NULL, FILE_PATH);
.....
/* Once handle status becomes CRIMANAPLAYER_STATUS_WAIT_PREP ... */
/* Get playback work buffer parameters */
criManaPlayer_GetPlaybackWorkParam(mana, &config_b, &config_ex);
/* Calculate and allocate playback work buffer size */
ply_work_size = criManaPlayer_CalculatePlaybackWorkSize(mana, &config_b, &config_ex);
ply_work = malloc(ply_work_size);
criManaPlayer_SetPlaybackWork(mana, &config_b, &config_ex, ply_work, ply_work_size);
void criManaPlayer_DecodeHeader(CriManaPlayerHn player)
Request header decoding.
void criManaPlayer_SetFile(CriManaPlayerHn player, CriFsBinderHn bndrhn, const CriChar8 *path)
Set movie file.
Playback work parameter structure (extended)
Definition: cri_mana.h:704
Releasing playback work memory
Because the playback work buffer memory may be used even after playback, do not immediately destroy the memory after playback. If you want to just temporarily release memory for reusing the player handle after playback finishes or stops, always release the memory after calling the criManaPlayer_FreePlaybackWork function. It's OK to unconditionally release the playback work memory if it is after the handle has been destroyed.
[Note] Registering a user allocator
When registering a user allocator (see below for more on user allocators), you do not need to call the criManaPlayer_SetPlaybackWork function. It will allocate the playback work memory at the necessary timing through the user allocator.

Metadata Work Buffers

Unlike other work buffers, only metadata work buffers require a memory function.
Use criManaPlayer_SetMetaDataWorkAllocator() to register a metadata memory function.
Memory allocation functions, memory release functions, user object points, and flags for using metadata are specified by arguments. (Specifying flags for metadata use is not currently supported.)

Seek and cuepoint information is currently included in the metadata. If you are not using seek playback and cuepoints, then it will not allocate memory itself unless a memory function is registered.
The memory function that is registered will be called while the header is being processed. The memory function will be generated from the decoding thread side when using multi-thread decoding. If the memory allocation function you are using is not thread safe, then give it exclusive control on the application side.

/* Create handle */
mana = criManaPlayer_Create(hn_work, hn_work_size);
/* Register metadata memory functions */
criManaPlayer_SetMetaDataWorkAllocator(mana, meta_alloc, meta_free, NULL, 0);
/* Begin header analysis */
criManaPlayer_SetFile(mana, NULL, FILE_PATH);
void criManaPlayer_SetMetaDataWorkAllocator(CriManaPlayerHn player, CriManaMetaMallocFunc allocfunc, CriManaMetaFreeFunc freefunc, void *obj, CriManaMetaFlag meta_flag)
Register meta data allocator.

Using the Application's Own Memory Management (User Allocator Registration Function)

You can define the Sofdec2 memory allocation/release function and register it in the library on the application side.
When registering the memory allocation/release function, the application will need to calculate the work buffer size and register the buffer.
Specify NULL for each work buffer setting function buffer address when registering a memory function.
The Sofdec2 library will call the registered function when necessary and allocate/release the required memory.
When using the function registration, the work buffer may use the function to partition the memory into more discrete units than when specifying them individually and allocate them.

/* Allocate memory */
void *user_alloc(void *obj, CriUint32 size)
{
void *ptr;
ptr = malloc(size);
return ptr;
}
/* Release memory */
void tutil_free(void *obj, void *ptr)
{
free(ptr);
}
....
/* Register memory function */
criMana_SetUserAllocator(user_alloc, user_free, NULL);
....
/* Initialize Sofdec2 library */
criMana_Initialize(&lib_config, NULL, 0);
/* Create playback handle */
mana = criManaPlayer_Create(NULL, 0);
....
/* Playback work setting not required */
//criManaPlayer_SetPlaybackWork(mana, &config_b, NULL, ply_work, ply_work_size);
void criMana_SetUserAllocator(CriManaMallocFunc malloc_func, CriManaFreeFunc free_func, void *obj)
Register user allocator.