Add opj_codec_set_threads() in public API and propagate resulting thread pool to tcd level
By default, only the main thread is used. If opj_codec_set_threads() is not used, but the OPJ_NUM_THREADS environment variable is set, its value will be used to initialize the number of threads. The value can be either an integer number, or "ALL_CPUS". If OPJ_NUM_THREADS is set and this function is called, this function will override the behaviour of the environment variable.
This commit is contained in:
parent
54179fe1d5
commit
d4b7f03cfa
|
@ -5944,6 +5944,32 @@ void opj_j2k_setup_decoder(opj_j2k_t *j2k, opj_dparameters_t *parameters)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
OPJ_BOOL opj_j2k_set_threads(opj_j2k_t *j2k, OPJ_UINT32 num_threads)
|
||||||
|
{
|
||||||
|
if( opj_has_thread_support() )
|
||||||
|
{
|
||||||
|
opj_thread_pool_destroy(j2k->m_tp);
|
||||||
|
j2k->m_tp = opj_thread_pool_create((int)num_threads);
|
||||||
|
if( j2k->m_tp == 0 )
|
||||||
|
{
|
||||||
|
j2k->m_tp = opj_thread_pool_create(0);
|
||||||
|
return OPJ_FALSE;
|
||||||
|
}
|
||||||
|
return OPJ_TRUE;
|
||||||
|
}
|
||||||
|
return OPJ_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int opj_j2k_get_default_thread_count()
|
||||||
|
{
|
||||||
|
const char* num_threads = getenv("OPJ_NUM_THREADS");
|
||||||
|
if( num_threads == NULL || !opj_has_thread_support() )
|
||||||
|
return 0;
|
||||||
|
if( strcmp(num_threads, "ALL_CPUS") == 0 )
|
||||||
|
return opj_get_num_cpus();
|
||||||
|
return atoi(num_threads);
|
||||||
|
}
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------- */
|
/* ----------------------------------------------------------------------- */
|
||||||
/* J2K encoder interface */
|
/* J2K encoder interface */
|
||||||
/* ----------------------------------------------------------------------- */
|
/* ----------------------------------------------------------------------- */
|
||||||
|
@ -5981,6 +6007,17 @@ opj_j2k_t* opj_j2k_create_compress(void)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
l_j2k->m_tp = opj_thread_pool_create(opj_j2k_get_default_thread_count());
|
||||||
|
if( !l_j2k->m_tp )
|
||||||
|
{
|
||||||
|
l_j2k->m_tp = opj_thread_pool_create(0);
|
||||||
|
}
|
||||||
|
if( !l_j2k->m_tp )
|
||||||
|
{
|
||||||
|
opj_j2k_destroy(l_j2k);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
return l_j2k;
|
return l_j2k;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7486,7 +7523,7 @@ static OPJ_BOOL opj_j2k_copy_default_tcp_and_create_tcd ( opj_j2k_t * p_j2
|
||||||
return OPJ_FALSE;
|
return OPJ_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !opj_tcd_init(p_j2k->m_tcd, l_image, &(p_j2k->m_cp)) ) {
|
if ( !opj_tcd_init(p_j2k->m_tcd, l_image, &(p_j2k->m_cp), p_j2k->m_tp) ) {
|
||||||
opj_tcd_destroy(p_j2k->m_tcd);
|
opj_tcd_destroy(p_j2k->m_tcd);
|
||||||
p_j2k->m_tcd = 00;
|
p_j2k->m_tcd = 00;
|
||||||
opj_event_msg(p_manager, EVT_ERROR, "Cannot decode tile, memory error\n");
|
opj_event_msg(p_manager, EVT_ERROR, "Cannot decode tile, memory error\n");
|
||||||
|
@ -7567,6 +7604,9 @@ void opj_j2k_destroy (opj_j2k_t *p_j2k)
|
||||||
opj_image_destroy(p_j2k->m_output_image);
|
opj_image_destroy(p_j2k->m_output_image);
|
||||||
p_j2k->m_output_image = NULL;
|
p_j2k->m_output_image = NULL;
|
||||||
|
|
||||||
|
opj_thread_pool_destroy(p_j2k->m_tp);
|
||||||
|
p_j2k->m_tp = NULL;
|
||||||
|
|
||||||
opj_free(p_j2k);
|
opj_free(p_j2k);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8658,6 +8698,17 @@ opj_j2k_t* opj_j2k_create_decompress(void)
|
||||||
return 00;
|
return 00;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
l_j2k->m_tp = opj_thread_pool_create(opj_j2k_get_default_thread_count());
|
||||||
|
if( !l_j2k->m_tp )
|
||||||
|
{
|
||||||
|
l_j2k->m_tp = opj_thread_pool_create(0);
|
||||||
|
}
|
||||||
|
if( !l_j2k->m_tp )
|
||||||
|
{
|
||||||
|
opj_j2k_destroy(l_j2k);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
return l_j2k;
|
return l_j2k;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10934,7 +10985,7 @@ static OPJ_BOOL opj_j2k_create_tcd( opj_j2k_t *p_j2k,
|
||||||
return OPJ_FALSE;
|
return OPJ_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!opj_tcd_init(p_j2k->m_tcd,p_j2k->m_private_image,&p_j2k->m_cp)) {
|
if (!opj_tcd_init(p_j2k->m_tcd,p_j2k->m_private_image,&p_j2k->m_cp, p_j2k->m_tp)) {
|
||||||
opj_tcd_destroy(p_j2k->m_tcd);
|
opj_tcd_destroy(p_j2k->m_tcd);
|
||||||
p_j2k->m_tcd = 00;
|
p_j2k->m_tcd = 00;
|
||||||
return OPJ_FALSE;
|
return OPJ_FALSE;
|
||||||
|
|
|
@ -589,6 +589,12 @@ typedef struct opj_j2k
|
||||||
|
|
||||||
/** the current tile coder/decoder **/
|
/** the current tile coder/decoder **/
|
||||||
struct opj_tcd * m_tcd;
|
struct opj_tcd * m_tcd;
|
||||||
|
|
||||||
|
/** Number of threads to use */
|
||||||
|
int m_num_threads;
|
||||||
|
|
||||||
|
/** Thread pool */
|
||||||
|
opj_thread_pool_t* m_tp;
|
||||||
}
|
}
|
||||||
opj_j2k_t;
|
opj_j2k_t;
|
||||||
|
|
||||||
|
@ -607,6 +613,8 @@ Decoding parameters are returned in j2k->cp.
|
||||||
*/
|
*/
|
||||||
void opj_j2k_setup_decoder(opj_j2k_t *j2k, opj_dparameters_t *parameters);
|
void opj_j2k_setup_decoder(opj_j2k_t *j2k, opj_dparameters_t *parameters);
|
||||||
|
|
||||||
|
OPJ_BOOL opj_j2k_set_threads(opj_j2k_t *j2k, OPJ_UINT32 num_threads);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a J2K compression structure
|
* Creates a J2K compression structure
|
||||||
*
|
*
|
||||||
|
|
|
@ -1767,6 +1767,11 @@ void opj_jp2_setup_decoder(opj_jp2_t *jp2, opj_dparameters_t *parameters)
|
||||||
jp2->ignore_pclr_cmap_cdef = parameters->flags & OPJ_DPARAMETERS_IGNORE_PCLR_CMAP_CDEF_FLAG;
|
jp2->ignore_pclr_cmap_cdef = parameters->flags & OPJ_DPARAMETERS_IGNORE_PCLR_CMAP_CDEF_FLAG;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
OPJ_BOOL opj_jp2_set_threads(opj_jp2_t *jp2, OPJ_UINT32 num_threads)
|
||||||
|
{
|
||||||
|
return opj_j2k_set_threads(jp2->j2k, num_threads);
|
||||||
|
}
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------- */
|
/* ----------------------------------------------------------------------- */
|
||||||
/* JP2 encoder interface */
|
/* JP2 encoder interface */
|
||||||
/* ----------------------------------------------------------------------- */
|
/* ----------------------------------------------------------------------- */
|
||||||
|
|
|
@ -243,6 +243,8 @@ Decoding parameters are returned in jp2->j2k->cp.
|
||||||
*/
|
*/
|
||||||
void opj_jp2_setup_decoder(opj_jp2_t *jp2, opj_dparameters_t *parameters);
|
void opj_jp2_setup_decoder(opj_jp2_t *jp2, opj_dparameters_t *parameters);
|
||||||
|
|
||||||
|
OPJ_BOOL opj_jp2_set_threads(opj_jp2_t *jp2, OPJ_UINT32 num_threads);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Decode an image from a JPEG-2000 file stream
|
* Decode an image from a JPEG-2000 file stream
|
||||||
* @param jp2 JP2 decompressor handle
|
* @param jp2 JP2 decompressor handle
|
||||||
|
|
|
@ -239,6 +239,9 @@ opj_codec_t* OPJ_CALLCONV opj_create_decompress(OPJ_CODEC_FORMAT p_format)
|
||||||
OPJ_UINT32 res_factor,
|
OPJ_UINT32 res_factor,
|
||||||
struct opj_event_mgr * p_manager)) opj_j2k_set_decoded_resolution_factor;
|
struct opj_event_mgr * p_manager)) opj_j2k_set_decoded_resolution_factor;
|
||||||
|
|
||||||
|
l_codec->opj_set_threads =
|
||||||
|
(OPJ_BOOL (*) ( void * p_codec, OPJ_UINT32 num_threads )) opj_j2k_set_threads;
|
||||||
|
|
||||||
l_codec->m_codec = opj_j2k_create_decompress();
|
l_codec->m_codec = opj_j2k_create_decompress();
|
||||||
|
|
||||||
if (! l_codec->m_codec) {
|
if (! l_codec->m_codec) {
|
||||||
|
@ -315,6 +318,9 @@ opj_codec_t* OPJ_CALLCONV opj_create_decompress(OPJ_CODEC_FORMAT p_format)
|
||||||
OPJ_UINT32 res_factor,
|
OPJ_UINT32 res_factor,
|
||||||
opj_event_mgr_t * p_manager)) opj_jp2_set_decoded_resolution_factor;
|
opj_event_mgr_t * p_manager)) opj_jp2_set_decoded_resolution_factor;
|
||||||
|
|
||||||
|
l_codec->opj_set_threads =
|
||||||
|
(OPJ_BOOL (*) ( void * p_codec, OPJ_UINT32 num_threads )) opj_jp2_set_threads;
|
||||||
|
|
||||||
l_codec->m_codec = opj_jp2_create(OPJ_TRUE);
|
l_codec->m_codec = opj_jp2_create(OPJ_TRUE);
|
||||||
|
|
||||||
if (! l_codec->m_codec) {
|
if (! l_codec->m_codec) {
|
||||||
|
@ -354,6 +360,18 @@ void OPJ_CALLCONV opj_set_default_decoder_parameters(opj_dparameters_t *paramete
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
OPJ_API OPJ_CALLCONV opj_codec_set_threads(opj_codec_t *p_codec,
|
||||||
|
int num_threads)
|
||||||
|
{
|
||||||
|
if (p_codec ) {
|
||||||
|
opj_codec_private_t * l_codec = (opj_codec_private_t *) p_codec;
|
||||||
|
|
||||||
|
return l_codec->opj_set_threads(l_codec->m_codec, num_threads);
|
||||||
|
}
|
||||||
|
return OPJ_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
OPJ_BOOL OPJ_CALLCONV opj_setup_decoder(opj_codec_t *p_codec,
|
OPJ_BOOL OPJ_CALLCONV opj_setup_decoder(opj_codec_t *p_codec,
|
||||||
opj_dparameters_t *parameters
|
opj_dparameters_t *parameters
|
||||||
)
|
)
|
||||||
|
|
|
@ -1262,6 +1262,25 @@ OPJ_API void OPJ_CALLCONV opj_set_default_decoder_parameters(opj_dparameters_t *
|
||||||
OPJ_API OPJ_BOOL OPJ_CALLCONV opj_setup_decoder(opj_codec_t *p_codec,
|
OPJ_API OPJ_BOOL OPJ_CALLCONV opj_setup_decoder(opj_codec_t *p_codec,
|
||||||
opj_dparameters_t *parameters );
|
opj_dparameters_t *parameters );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allocates worker threads for the compressor/decompressor.
|
||||||
|
*
|
||||||
|
* By default, only the main thread is used. If this function is not used,
|
||||||
|
* but the OPJ_NUM_THREADS environment variable is set, its value will be
|
||||||
|
* used to initialize the number of threads. The value can be either an integer
|
||||||
|
* number, or "ALL_CPUS". If OPJ_NUM_THREADS is set and this function is called,
|
||||||
|
* this function will override the behaviour of the environment variable.
|
||||||
|
*
|
||||||
|
* Note: currently only has effect on the decompressor.
|
||||||
|
*
|
||||||
|
* @param p_codec decompressor handler
|
||||||
|
* @param num_threads number of threads.
|
||||||
|
*
|
||||||
|
* @return OPJ_TRUE if the decoder is correctly set
|
||||||
|
*/
|
||||||
|
OPJ_API OPJ_BOOL OPJ_CALLCONV opj_codec_set_threads(opj_codec_t *p_codec,
|
||||||
|
int num_threads);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Decodes an image header.
|
* Decodes an image header.
|
||||||
*
|
*
|
||||||
|
|
|
@ -113,6 +113,7 @@ typedef struct opj_codec_private
|
||||||
OPJ_BOOL (*opj_set_decoded_resolution_factor) ( void * p_codec,
|
OPJ_BOOL (*opj_set_decoded_resolution_factor) ( void * p_codec,
|
||||||
OPJ_UINT32 res_factor,
|
OPJ_UINT32 res_factor,
|
||||||
opj_event_mgr_t * p_manager);
|
opj_event_mgr_t * p_manager);
|
||||||
|
|
||||||
} m_decompression;
|
} m_decompression;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -157,6 +158,9 @@ typedef struct opj_codec_private
|
||||||
void (*opj_dump_codec) (void * p_codec, OPJ_INT32 info_flag, FILE* output_stream);
|
void (*opj_dump_codec) (void * p_codec, OPJ_INT32 info_flag, FILE* output_stream);
|
||||||
opj_codestream_info_v2_t* (*opj_get_codec_info)(void* p_codec);
|
opj_codestream_info_v2_t* (*opj_get_codec_info)(void* p_codec);
|
||||||
opj_codestream_index_t* (*opj_get_codec_index)(void* p_codec);
|
opj_codestream_index_t* (*opj_get_codec_index)(void* p_codec);
|
||||||
|
|
||||||
|
/** Set number of threads */
|
||||||
|
OPJ_BOOL (*opj_set_threads) ( void * p_codec, OPJ_UINT32 num_threads );
|
||||||
}
|
}
|
||||||
opj_codec_private_t;
|
opj_codec_private_t;
|
||||||
|
|
||||||
|
|
|
@ -580,7 +580,8 @@ OPJ_BOOL opj_tcd_rateallocate( opj_tcd_t *tcd,
|
||||||
|
|
||||||
OPJ_BOOL opj_tcd_init( opj_tcd_t *p_tcd,
|
OPJ_BOOL opj_tcd_init( opj_tcd_t *p_tcd,
|
||||||
opj_image_t * p_image,
|
opj_image_t * p_image,
|
||||||
opj_cp_t * p_cp )
|
opj_cp_t * p_cp,
|
||||||
|
opj_thread_pool_t* p_tp )
|
||||||
{
|
{
|
||||||
p_tcd->image = p_image;
|
p_tcd->image = p_image;
|
||||||
p_tcd->cp = p_cp;
|
p_tcd->cp = p_cp;
|
||||||
|
@ -597,6 +598,7 @@ OPJ_BOOL opj_tcd_init( opj_tcd_t *p_tcd,
|
||||||
|
|
||||||
p_tcd->tcd_image->tiles->numcomps = p_image->numcomps;
|
p_tcd->tcd_image->tiles->numcomps = p_image->numcomps;
|
||||||
p_tcd->tp_pos = p_cp->m_specific_param.m_enc.m_tp_pos;
|
p_tcd->tp_pos = p_cp->m_specific_param.m_enc.m_tp_pos;
|
||||||
|
p_tcd->thread_pool = p_tp;
|
||||||
|
|
||||||
return OPJ_TRUE;
|
return OPJ_TRUE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -220,6 +220,8 @@ typedef struct opj_tcd
|
||||||
OPJ_UINT32 tcd_tileno;
|
OPJ_UINT32 tcd_tileno;
|
||||||
/** tell if the tcd is a decoder. */
|
/** tell if the tcd is a decoder. */
|
||||||
OPJ_UINT32 m_is_decoder : 1;
|
OPJ_UINT32 m_is_decoder : 1;
|
||||||
|
/** Thread pool */
|
||||||
|
opj_thread_pool_t* thread_pool;
|
||||||
} opj_tcd_t;
|
} opj_tcd_t;
|
||||||
|
|
||||||
/** @name Exported functions */
|
/** @name Exported functions */
|
||||||
|
@ -249,12 +251,14 @@ void opj_tcd_destroy(opj_tcd_t *tcd);
|
||||||
* @param p_tcd TCD handle.
|
* @param p_tcd TCD handle.
|
||||||
* @param p_image raw image.
|
* @param p_image raw image.
|
||||||
* @param p_cp coding parameters.
|
* @param p_cp coding parameters.
|
||||||
|
* @param p_tp thread pool
|
||||||
*
|
*
|
||||||
* @return true if the encoding values could be set (false otherwise).
|
* @return true if the encoding values could be set (false otherwise).
|
||||||
*/
|
*/
|
||||||
OPJ_BOOL opj_tcd_init( opj_tcd_t *p_tcd,
|
OPJ_BOOL opj_tcd_init( opj_tcd_t *p_tcd,
|
||||||
opj_image_t * p_image,
|
opj_image_t * p_image,
|
||||||
opj_cp_t * p_cp );
|
opj_cp_t * p_cp,
|
||||||
|
opj_thread_pool_t* p_tp);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allocates memory for decoding a specific tile.
|
* Allocates memory for decoding a specific tile.
|
||||||
|
|
Loading…
Reference in New Issue