Skip to content

Commit

Permalink
Add multithreading support in the T1 (entropy phase) encoder
Browse files Browse the repository at this point in the history
- API wise, opj_codec_set_threads() can be used on the encoding side
- opj_compress has a -threads switch similar to opj_uncompress
  • Loading branch information
rouault committed May 20, 2020
1 parent 1d358f2 commit 97eb7e0
Show file tree
Hide file tree
Showing 6 changed files with 239 additions and 129 deletions.
35 changes: 32 additions & 3 deletions src/bin/jp2/opj_compress.c
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,10 @@ static void encode_help_display(void)
fprintf(stdout, " Currently supports only RPCL order.\n");
fprintf(stdout, "-C <comment>\n");
fprintf(stdout, " Add <comment> in the comment marker segment.\n");
if (opj_has_thread_support()) {
fprintf(stdout, " -threads <num_threads|ALL_CPUS>\n"
" Number of threads to use for encoding or ALL_CPUS for all available cores.\n");
}
/* UniPG>> */
#ifdef USE_JPWL
fprintf(stdout, "-W <params>\n");
Expand Down Expand Up @@ -579,7 +583,8 @@ static int parse_cmdline_encoder(int argc, char **argv,
img_fol_t *img_fol, raw_cparameters_t *raw_cp, char *indexfilename,
size_t indexfilename_size,
int* pOutFramerate,
OPJ_BOOL* pOutPLT)
OPJ_BOOL* pOutPLT,
int* pOutNumThreads)
{
OPJ_UINT32 i, j;
int totlen, c;
Expand All @@ -596,7 +601,8 @@ static int parse_cmdline_encoder(int argc, char **argv,
{"jpip", NO_ARG, NULL, 'J'},
{"mct", REQ_ARG, NULL, 'Y'},
{"IMF", REQ_ARG, NULL, 'Z'},
{"PLT", NO_ARG, NULL, 'A'}
{"PLT", NO_ARG, NULL, 'A'},
{"threads", REQ_ARG, NULL, 'B'}
};

/* parse the command line */
Expand Down Expand Up @@ -1679,6 +1685,19 @@ static int parse_cmdline_encoder(int argc, char **argv,
}
break;

/* ----------------------------------------------------- */
case 'B': { /* Number of threads */
if (strcmp(opj_optarg, "ALL_CPUS") == 0) {
*pOutNumThreads = opj_get_num_cpus();
if (*pOutNumThreads == 1) {
*pOutNumThreads = 0;
}
} else {
sscanf(opj_optarg, "%d", pOutNumThreads);
}
}
break;

/* ------------------------------------------------------ */


Expand Down Expand Up @@ -1860,6 +1879,7 @@ int main(int argc, char **argv)
OPJ_FLOAT64 t = opj_clock();

OPJ_BOOL PLT = OPJ_FALSE;
int num_threads = 0;

/* set encoding parameters to default values */
opj_set_default_encoder_parameters(&parameters);
Expand All @@ -1880,7 +1900,7 @@ int main(int argc, char **argv)
parameters.tcp_mct = (char)
255; /* This will be set later according to the input image or the provided option */
if (parse_cmdline_encoder(argc, argv, &parameters, &img_fol, &raw_cp,
indexfilename, sizeof(indexfilename), &framerate, &PLT) == 1) {
indexfilename, sizeof(indexfilename), &framerate, &PLT, &num_threads) == 1) {
ret = 1;
goto fin;
}
Expand Down Expand Up @@ -2141,6 +2161,15 @@ int main(int argc, char **argv)
}
}

if (num_threads >= 1 &&
!opj_codec_set_threads(l_codec, num_threads)) {
fprintf(stderr, "failed to set number of threads\n");
opj_destroy_codec(l_codec);
opj_image_destroy(image);
ret = 1;
goto fin;
}

/* open a byte stream for writing and allocate memory for all tiles */
l_stream = opj_stream_create_default_file_stream(parameters.outfile, OPJ_FALSE);
if (! l_stream) {
Expand Down
6 changes: 6 additions & 0 deletions src/lib/openjp2/openjpeg.c
Original file line number Diff line number Diff line change
Expand Up @@ -657,6 +657,9 @@ opj_codec_t* OPJ_CALLCONV opj_create_compress(OPJ_CODEC_FORMAT p_format)
const char* const*,
struct opj_event_mgr *)) opj_j2k_encoder_set_extra_options;

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_compress();
if (! l_codec->m_codec) {
opj_free(l_codec);
Expand Down Expand Up @@ -700,6 +703,9 @@ opj_codec_t* OPJ_CALLCONV opj_create_compress(OPJ_CODEC_FORMAT p_format)
const char* const*,
struct opj_event_mgr *)) opj_jp2_encoder_set_extra_options;

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_FALSE);
if (! l_codec->m_codec) {
opj_free(l_codec);
Expand Down
11 changes: 5 additions & 6 deletions src/lib/openjp2/openjpeg.h
Original file line number Diff line number Diff line change
Expand Up @@ -1348,15 +1348,14 @@ OPJ_API OPJ_BOOL OPJ_CALLCONV opj_setup_decoder(opj_codec_t *p_codec,
* 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.
*
* Currently this function must be called after opj_setup_decoder() and
* before opj_read_header().
* This function must be called after opj_setup_decoder() and
* before opj_read_header() for the decoding side, or after opj_setup_encoder()
* and before opj_start_compress() for the encoding side.
*
* Note: currently only has effect on the decompressor.
*
* @param p_codec decompressor handler
* @param p_codec decompressor or compressor handler
* @param num_threads number of threads.
*
* @return OPJ_TRUE if the decoder is correctly set
* @return OPJ_TRUE if the function is successful.
*/
OPJ_API OPJ_BOOL OPJ_CALLCONV opj_codec_set_threads(opj_codec_t *p_codec,
int num_threads);
Expand Down
Loading

0 comments on commit 97eb7e0

Please sign in to comment.