OpenJPEG can decode in lower resolution or decode only a number of enhancement layers.
Unified · Split
| @@ -24,6 +24,7 @@ · 23 unmodified lines | |||
| 24 | * JPEG 2000 decoder using libopenjpeg | 24 | * JPEG 2000 decoder using libopenjpeg |
| 25 | */ | 25 | */ |
| 26 | 26 | ||
| 27 | #include "libavutil/opt.h" | ||
| 27 | #include "libavutil/imgutils.h" | 28 | #include "libavutil/imgutils.h" |
| 28 | #include "avcodec.h" | 29 | #include "avcodec.h" |
| 29 | #include "libavutil/intreadwrite.h" | 30 | #include "libavutil/intreadwrite.h" |
| @@ -35,8 +36,11 @@ · 5 unmodified lines | |||
| 35 | #define JP2_SIG_VALUE 0x0D0A870A | 36 | #define JP2_SIG_VALUE 0x0D0A870A |
| 36 | 37 | ||
| 37 | typedef struct { | 38 | typedef struct { |
| 39 | AVClass *class; | ||
| 38 | opj_dparameters_t dec_params; | 40 | opj_dparameters_t dec_params; |
| 39 | AVFrame image; | 41 | AVFrame image; |
| 42 | int lowres; | ||
| 43 | int lowqual; | ||
| 40 | } LibOpenJPEGContext; | 44 | } LibOpenJPEGContext; |
| 41 | 45 | ||
| 42 | static int check_image_attributes(opj_image_t *image) | 46 | static int check_image_attributes(opj_image_t *image) |
| @@ -104,6 +108,8 @@ static int libopenjpeg_decode_frame(AVCodecContext *avctx, · 61 unmodified lines | |||
| 104 | opj_set_event_mgr((opj_common_ptr)dec, NULL, NULL); | 108 | opj_set_event_mgr((opj_common_ptr)dec, NULL, NULL); |
| 105 | 109 | ||
| 106 | ctx->dec_params.cp_limit_decoding = LIMIT_TO_MAIN_HEADER; | 110 | ctx->dec_params.cp_limit_decoding = LIMIT_TO_MAIN_HEADER; |
| 111 | ctx->dec_params.cp_reduce = ctx->lowres; | ||
| 112 | ctx->dec_params.cp_layer = ctx->lowqual; | ||
| 107 | // Tie decoder with decoding parameters | 113 | // Tie decoder with decoding parameters |
| 108 | opj_setup_decoder(dec, &ctx->dec_params); | 114 | opj_setup_decoder(dec, &ctx->dec_params); |
| 109 | stream = opj_cio_open((opj_common_ptr)dec, buf, buf_size); | 115 | stream = opj_cio_open((opj_common_ptr)dec, buf, buf_size); |
| @@ -123,6 +129,12 @@ static int libopenjpeg_decode_frame(AVCodecContext *avctx, · 13 unmodified lines | |||
| 123 | } | 129 | } |
| 124 | width = image->x1 - image->x0; | 130 | width = image->x1 - image->x0; |
| 125 | height = image->y1 - image->y0; | 131 | height = image->y1 - image->y0; |
| 132 | |||
| 133 | if (ctx->lowres) { | ||
| 134 | width = (width + (1 << ctx->lowres) - 1) >> ctx->lowres; | ||
| 135 | height = (height + (1 << ctx->lowres) - 1) >> ctx->lowres; | ||
| 136 | } | ||
| 137 | |||
| 126 | if(av_image_check_size(width, height, 0, avctx) < 0) { | 138 | if(av_image_check_size(width, height, 0, avctx) < 0) { |
| 127 | av_log(avctx, AV_LOG_ERROR, "%dx%d dimension invalid.\n", width, height); | 139 | av_log(avctx, AV_LOG_ERROR, "%dx%d dimension invalid.\n", width, height); |
| 128 | goto done; | 140 | goto done; |
| @@ -208,6 +220,21 @@ static av_cold int libopenjpeg_decode_close(AVCodecContext *avctx) · 79 unmodified lines | |||
| 208 | return 0 ; | 220 | return 0 ; |
| 209 | } | 221 | } |
| 210 | 222 | ||
| 223 | #define OFFSET(x) offsetof(LibOpenJPEGContext, x) | ||
| 224 | #define VD AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM | ||
| 225 | |||
| 226 | static const AVOption options[] = { | ||
| 227 | { "lowqual", "Limit the number of layers used for decoding", OFFSET(lowqual), AV_OPT_TYPE_INT, { 0 }, 0, INT_MAX, VD }, | ||
| 228 | { "lowres", "Lower the decoding resolution by a power of two", OFFSET(lowres), AV_OPT_TYPE_INT, { 0 }, 0, INT_MAX, VD }, | ||
| 229 | { NULL }, | ||
| 230 | }; | ||
| 231 | |||
| 232 | static const AVClass class = { | ||
| 233 | .class_name = "libopenjpeg", | ||
| 234 | .item_name = av_default_item_name, | ||
| 235 | .option = options, | ||
| 236 | .version = LIBAVUTIL_VERSION_INT, | ||
| 237 | }; | ||
| 211 | 238 | ||
| 212 | AVCodec ff_libopenjpeg_decoder = { | 239 | AVCodec ff_libopenjpeg_decoder = { |
| 213 | .name = "libopenjpeg", | 240 | .name = "libopenjpeg", |
| @@ -219,5 +246,6 @@ AVCodec ff_libopenjpeg_decoder = { · 5 unmodified lines | |||
| 219 | .decode = libopenjpeg_decode_frame, | 246 | .decode = libopenjpeg_decode_frame, |
| 220 | .capabilities = CODEC_CAP_DR1 | CODEC_CAP_FRAME_THREADS, | 247 | .capabilities = CODEC_CAP_DR1 | CODEC_CAP_FRAME_THREADS, |
| 221 | .long_name = NULL_IF_CONFIG_SMALL("OpenJPEG based JPEG 2000 decoder"), | 248 | .long_name = NULL_IF_CONFIG_SMALL("OpenJPEG based JPEG 2000 decoder"), |
| 249 | .priv_class = &class, | ||
| 222 | .init_thread_copy = ONLY_IF_THREADS_ENABLED(libopenjpeg_decode_init_thread_copy), | 250 | .init_thread_copy = ONLY_IF_THREADS_ENABLED(libopenjpeg_decode_init_thread_copy), |
| 223 | }; | 251 | }; |