Skip to content
Snippets Groups Projects
Commit b8bb9c02 authored by Jean First's avatar Jean First Committed by Ronald S. Bultje
Browse files

Enable multithreding when decoding with libopenjpeg


Enable multithreding when decoding with libopenjpeg

Signed-off-by: default avatarMichael Niedermayer <michaelni@gmx.at>
Signed-off-by: default avatarRonald S. Bultje <rsbultje@gmail.com>
parent 27209bb1
No related branches found
No related tags found
No related merge requests found
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include "libavutil/imgutils.h" #include "libavutil/imgutils.h"
#include "avcodec.h" #include "avcodec.h"
#include "libavutil/intreadwrite.h" #include "libavutil/intreadwrite.h"
#include "thread.h"
#define OPJ_STATIC #define OPJ_STATIC
#include <openjpeg.h> #include <openjpeg.h>
...@@ -57,6 +58,14 @@ static av_cold int libopenjpeg_decode_init(AVCodecContext *avctx) ...@@ -57,6 +58,14 @@ static av_cold int libopenjpeg_decode_init(AVCodecContext *avctx)
return 0; return 0;
} }
static av_cold int libopenjpeg_decode_init_thread_copy(AVCodecContext *avctx)
{
LibOpenJPEGContext *ctx = avctx->priv_data;
avctx->coded_frame = &ctx->image;
return 0;
}
static int libopenjpeg_decode_frame(AVCodecContext *avctx, static int libopenjpeg_decode_frame(AVCodecContext *avctx,
void *data, int *data_size, void *data, int *data_size,
AVPacket *avpkt) AVPacket *avpkt)
...@@ -94,7 +103,7 @@ static int libopenjpeg_decode_frame(AVCodecContext *avctx, ...@@ -94,7 +103,7 @@ static int libopenjpeg_decode_frame(AVCodecContext *avctx,
} }
opj_set_event_mgr((opj_common_ptr)dec, NULL, NULL); opj_set_event_mgr((opj_common_ptr)dec, NULL, NULL);
ctx->dec_params.cp_reduce = avctx->lowres; ctx->dec_params.cp_limit_decoding = LIMIT_TO_MAIN_HEADER;
// Tie decoder with decoding parameters // Tie decoder with decoding parameters
opj_setup_decoder(dec, &ctx->dec_params); opj_setup_decoder(dec, &ctx->dec_params);
stream = opj_cio_open((opj_common_ptr)dec, buf, buf_size); stream = opj_cio_open((opj_common_ptr)dec, buf, buf_size);
...@@ -104,7 +113,7 @@ static int libopenjpeg_decode_frame(AVCodecContext *avctx, ...@@ -104,7 +113,7 @@ static int libopenjpeg_decode_frame(AVCodecContext *avctx,
return -1; return -1;
} }
// Decode the codestream // Decode the header only
image = opj_decode_with_info(dec, stream, NULL); image = opj_decode_with_info(dec, stream, NULL);
opj_cio_close(stream); opj_cio_close(stream);
if(!image) { if(!image) {
...@@ -112,8 +121,8 @@ static int libopenjpeg_decode_frame(AVCodecContext *avctx, ...@@ -112,8 +121,8 @@ static int libopenjpeg_decode_frame(AVCodecContext *avctx,
opj_destroy_decompress(dec); opj_destroy_decompress(dec);
return -1; return -1;
} }
width = image->comps[0].w << avctx->lowres; width = image->x1 - image->x0;
height = image->comps[0].h << avctx->lowres; height = image->y1 - image->y0;
if(av_image_check_size(width, height, 0, avctx) < 0) { if(av_image_check_size(width, height, 0, avctx) < 0) {
av_log(avctx, AV_LOG_ERROR, "%dx%d dimension invalid.\n", width, height); av_log(avctx, AV_LOG_ERROR, "%dx%d dimension invalid.\n", width, height);
goto done; goto done;
...@@ -139,13 +148,30 @@ static int libopenjpeg_decode_frame(AVCodecContext *avctx, ...@@ -139,13 +148,30 @@ static int libopenjpeg_decode_frame(AVCodecContext *avctx,
} }
if(picture->data[0]) if(picture->data[0])
avctx->release_buffer(avctx, picture); ff_thread_release_buffer(avctx, picture);
if(ff_thread_get_buffer(avctx, picture) < 0){
av_log(avctx, AV_LOG_ERROR, "ff_thread_get_buffer() failed\n");
return -1;
}
if(avctx->get_buffer(avctx, picture) < 0) { ff_thread_finish_setup(avctx);
av_log(avctx, AV_LOG_ERROR, "Couldn't allocate image buffer.\n");
ctx->dec_params.cp_limit_decoding = NO_LIMITATION;
ctx->dec_params.cp_reduce = avctx->lowres;
// Tie decoder with decoding parameters
opj_setup_decoder(dec, &ctx->dec_params);
stream = opj_cio_open((opj_common_ptr)dec, buf, buf_size);
if(!stream) {
av_log(avctx, AV_LOG_ERROR, "Codestream could not be opened for reading.\n");
opj_destroy_decompress(dec);
return -1; return -1;
} }
// Decode the codestream
image = opj_decode_with_info(dec, stream, NULL);
opj_cio_close(stream);
for(x = 0; x < image->numcomps; x++) { for(x = 0; x < image->numcomps; x++) {
adjust[x] = FFMAX(image->comps[x].prec - 8, 0); adjust[x] = FFMAX(image->comps[x].prec - 8, 0);
} }
...@@ -179,7 +205,7 @@ static av_cold int libopenjpeg_decode_close(AVCodecContext *avctx) ...@@ -179,7 +205,7 @@ static av_cold int libopenjpeg_decode_close(AVCodecContext *avctx)
LibOpenJPEGContext *ctx = avctx->priv_data; LibOpenJPEGContext *ctx = avctx->priv_data;
if(ctx->image.data[0]) if(ctx->image.data[0])
avctx->release_buffer(avctx, &ctx->image); ff_thread_release_buffer(avctx, &ctx->image);
return 0 ; return 0 ;
} }
...@@ -192,7 +218,8 @@ AVCodec ff_libopenjpeg_decoder = { ...@@ -192,7 +218,8 @@ AVCodec ff_libopenjpeg_decoder = {
.init = libopenjpeg_decode_init, .init = libopenjpeg_decode_init,
.close = libopenjpeg_decode_close, .close = libopenjpeg_decode_close,
.decode = libopenjpeg_decode_frame, .decode = libopenjpeg_decode_frame,
.capabilities = CODEC_CAP_DR1, .capabilities = CODEC_CAP_DR1 | CODEC_CAP_FRAME_THREADS,
.max_lowres = 5, .max_lowres = 5,
.long_name = NULL_IF_CONFIG_SMALL("OpenJPEG based JPEG 2000 decoder"), .long_name = NULL_IF_CONFIG_SMALL("OpenJPEG based JPEG 2000 decoder"),
.init_thread_copy = ONLY_IF_THREADS_ENABLED(libopenjpeg_decode_init_thread_copy)
}; };
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment