annotate ffmpeg/libavcodec/libopenjpegdec.c @ 13:844d341cf643 tip

Back up before ISMIR
author Yading Song <yading.song@eecs.qmul.ac.uk>
date Thu, 31 Oct 2013 13:17:06 +0000
parents 6840f77b83aa
children
rev   line source
yading@10 1 /*
yading@10 2 * JPEG 2000 decoding support via OpenJPEG
yading@10 3 * Copyright (c) 2009 Jaikrishnan Menon <realityman@gmx.net>
yading@10 4 *
yading@10 5 * This file is part of FFmpeg.
yading@10 6 *
yading@10 7 * FFmpeg is free software; you can redistribute it and/or
yading@10 8 * modify it under the terms of the GNU Lesser General Public
yading@10 9 * License as published by the Free Software Foundation; either
yading@10 10 * version 2.1 of the License, or (at your option) any later version.
yading@10 11 *
yading@10 12 * FFmpeg is distributed in the hope that it will be useful,
yading@10 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
yading@10 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
yading@10 15 * Lesser General Public License for more details.
yading@10 16 *
yading@10 17 * You should have received a copy of the GNU Lesser General Public
yading@10 18 * License along with FFmpeg; if not, write to the Free Software
yading@10 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
yading@10 20 */
yading@10 21
yading@10 22 /**
yading@10 23 * @file
yading@10 24 * JPEG 2000 decoder using libopenjpeg
yading@10 25 */
yading@10 26
yading@10 27 #define OPJ_STATIC
yading@10 28
yading@10 29 #include "libavutil/common.h"
yading@10 30 #include "libavutil/intreadwrite.h"
yading@10 31 #include "libavutil/imgutils.h"
yading@10 32 #include "libavutil/pixfmt.h"
yading@10 33 #include "libavutil/opt.h"
yading@10 34 #include "avcodec.h"
yading@10 35 #include "thread.h"
yading@10 36
yading@10 37 #if HAVE_OPENJPEG_1_5_OPENJPEG_H
yading@10 38 # include <openjpeg-1.5/openjpeg.h>
yading@10 39 #else
yading@10 40 # include <openjpeg.h>
yading@10 41 #endif
yading@10 42
yading@10 43 #define JP2_SIG_TYPE 0x6A502020
yading@10 44 #define JP2_SIG_VALUE 0x0D0A870A
yading@10 45
yading@10 46 // pix_fmts with lower bpp have to be listed before
yading@10 47 // similar pix_fmts with higher bpp.
yading@10 48 #define RGB_PIXEL_FORMATS AV_PIX_FMT_RGB24,AV_PIX_FMT_RGBA,AV_PIX_FMT_RGB48,AV_PIX_FMT_RGBA64
yading@10 49 #define GRAY_PIXEL_FORMATS AV_PIX_FMT_GRAY8,AV_PIX_FMT_GRAY8A,AV_PIX_FMT_GRAY16
yading@10 50 #define YUV_PIXEL_FORMATS AV_PIX_FMT_YUV410P,AV_PIX_FMT_YUV411P,AV_PIX_FMT_YUVA420P, \
yading@10 51 AV_PIX_FMT_YUV420P,AV_PIX_FMT_YUV422P,AV_PIX_FMT_YUVA422P, \
yading@10 52 AV_PIX_FMT_YUV440P,AV_PIX_FMT_YUV444P,AV_PIX_FMT_YUVA444P, \
yading@10 53 AV_PIX_FMT_YUV420P9,AV_PIX_FMT_YUV422P9,AV_PIX_FMT_YUV444P9, \
yading@10 54 AV_PIX_FMT_YUVA420P9,AV_PIX_FMT_YUVA422P9,AV_PIX_FMT_YUVA444P9, \
yading@10 55 AV_PIX_FMT_YUV420P10,AV_PIX_FMT_YUV422P10,AV_PIX_FMT_YUV444P10, \
yading@10 56 AV_PIX_FMT_YUVA420P10,AV_PIX_FMT_YUVA422P10,AV_PIX_FMT_YUVA444P10, \
yading@10 57 AV_PIX_FMT_YUV420P12,AV_PIX_FMT_YUV422P12,AV_PIX_FMT_YUV444P12, \
yading@10 58 AV_PIX_FMT_YUV420P14,AV_PIX_FMT_YUV422P14,AV_PIX_FMT_YUV444P14, \
yading@10 59 AV_PIX_FMT_YUV420P16,AV_PIX_FMT_YUV422P16,AV_PIX_FMT_YUV444P16, \
yading@10 60 AV_PIX_FMT_YUVA420P16,AV_PIX_FMT_YUVA422P16,AV_PIX_FMT_YUVA444P16
yading@10 61
yading@10 62 #define XYZ_PIXEL_FORMATS AV_PIX_FMT_XYZ12
yading@10 63
yading@10 64 static const enum AVPixelFormat libopenjpeg_rgb_pix_fmts[] = {RGB_PIXEL_FORMATS};
yading@10 65 static const enum AVPixelFormat libopenjpeg_gray_pix_fmts[] = {GRAY_PIXEL_FORMATS};
yading@10 66 static const enum AVPixelFormat libopenjpeg_yuv_pix_fmts[] = {YUV_PIXEL_FORMATS};
yading@10 67 static const enum AVPixelFormat libopenjpeg_all_pix_fmts[] = {RGB_PIXEL_FORMATS,
yading@10 68 GRAY_PIXEL_FORMATS,
yading@10 69 YUV_PIXEL_FORMATS,
yading@10 70 XYZ_PIXEL_FORMATS};
yading@10 71
yading@10 72 typedef struct {
yading@10 73 AVClass *class;
yading@10 74 opj_dparameters_t dec_params;
yading@10 75 int lowqual;
yading@10 76 } LibOpenJPEGContext;
yading@10 77
yading@10 78 static inline int libopenjpeg_matches_pix_fmt(const opj_image_t *image, enum AVPixelFormat pix_fmt)
yading@10 79 {
yading@10 80 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
yading@10 81 int match = 1;
yading@10 82
yading@10 83 if (desc->nb_components != image->numcomps) {
yading@10 84 return 0;
yading@10 85 }
yading@10 86
yading@10 87 switch (desc->nb_components) {
yading@10 88 case 4: match = match && desc->comp[3].depth_minus1 + 1 >= image->comps[3].prec &&
yading@10 89 1 == image->comps[3].dx &&
yading@10 90 1 == image->comps[3].dy;
yading@10 91 case 3: match = match && desc->comp[2].depth_minus1 + 1 >= image->comps[2].prec &&
yading@10 92 1 << desc->log2_chroma_w == image->comps[2].dx &&
yading@10 93 1 << desc->log2_chroma_h == image->comps[2].dy;
yading@10 94 case 2: match = match && desc->comp[1].depth_minus1 + 1 >= image->comps[1].prec &&
yading@10 95 1 << desc->log2_chroma_w == image->comps[1].dx &&
yading@10 96 1 << desc->log2_chroma_h == image->comps[1].dy;
yading@10 97 case 1: match = match && desc->comp[0].depth_minus1 + 1 >= image->comps[0].prec &&
yading@10 98 1 == image->comps[0].dx &&
yading@10 99 1 == image->comps[0].dy;
yading@10 100 default:
yading@10 101 break;
yading@10 102 }
yading@10 103
yading@10 104 return match;
yading@10 105 }
yading@10 106
yading@10 107 static inline enum AVPixelFormat libopenjpeg_guess_pix_fmt(const opj_image_t *image) {
yading@10 108 int index;
yading@10 109 const enum AVPixelFormat *possible_fmts = NULL;
yading@10 110 int possible_fmts_nb = 0;
yading@10 111
yading@10 112 switch (image->color_space) {
yading@10 113 case CLRSPC_SRGB:
yading@10 114 possible_fmts = libopenjpeg_rgb_pix_fmts;
yading@10 115 possible_fmts_nb = FF_ARRAY_ELEMS(libopenjpeg_rgb_pix_fmts);
yading@10 116 break;
yading@10 117 case CLRSPC_GRAY:
yading@10 118 possible_fmts = libopenjpeg_gray_pix_fmts;
yading@10 119 possible_fmts_nb = FF_ARRAY_ELEMS(libopenjpeg_gray_pix_fmts);
yading@10 120 break;
yading@10 121 case CLRSPC_SYCC:
yading@10 122 possible_fmts = libopenjpeg_yuv_pix_fmts;
yading@10 123 possible_fmts_nb = FF_ARRAY_ELEMS(libopenjpeg_yuv_pix_fmts);
yading@10 124 break;
yading@10 125 default:
yading@10 126 possible_fmts = libopenjpeg_all_pix_fmts;
yading@10 127 possible_fmts_nb = FF_ARRAY_ELEMS(libopenjpeg_all_pix_fmts);
yading@10 128 break;
yading@10 129 }
yading@10 130
yading@10 131 for (index = 0; index < possible_fmts_nb; ++index) {
yading@10 132 if (libopenjpeg_matches_pix_fmt(image, possible_fmts[index])) {
yading@10 133 return possible_fmts[index];
yading@10 134 }
yading@10 135 }
yading@10 136
yading@10 137 return AV_PIX_FMT_NONE;
yading@10 138 }
yading@10 139
yading@10 140 static inline int libopenjpeg_ispacked(enum AVPixelFormat pix_fmt)
yading@10 141 {
yading@10 142 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
yading@10 143 int i, component_plane;
yading@10 144
yading@10 145 if (pix_fmt == AV_PIX_FMT_GRAY16)
yading@10 146 return 0;
yading@10 147
yading@10 148 component_plane = desc->comp[0].plane;
yading@10 149 for (i = 1; i < desc->nb_components; i++) {
yading@10 150 if (component_plane != desc->comp[i].plane)
yading@10 151 return 0;
yading@10 152 }
yading@10 153 return 1;
yading@10 154 }
yading@10 155
yading@10 156 static inline void libopenjpeg_copy_to_packed8(AVFrame *picture, opj_image_t *image) {
yading@10 157 uint8_t *img_ptr;
yading@10 158 int index, x, y, c;
yading@10 159 for (y = 0; y < picture->height; y++) {
yading@10 160 index = y*picture->width;
yading@10 161 img_ptr = picture->data[0] + y*picture->linesize[0];
yading@10 162 for (x = 0; x < picture->width; x++, index++) {
yading@10 163 for (c = 0; c < image->numcomps; c++) {
yading@10 164 *img_ptr++ = image->comps[c].data[index];
yading@10 165 }
yading@10 166 }
yading@10 167 }
yading@10 168 }
yading@10 169
yading@10 170 static inline void libopenjpeg_copy_to_packed16(AVFrame *picture, opj_image_t *image) {
yading@10 171 uint16_t *img_ptr;
yading@10 172 int index, x, y, c;
yading@10 173 int adjust[4];
yading@10 174 for (x = 0; x < image->numcomps; x++)
yading@10 175 adjust[x] = FFMAX(FFMIN(16 - image->comps[x].prec, 8), 0);
yading@10 176
yading@10 177 for (y = 0; y < picture->height; y++) {
yading@10 178 index = y*picture->width;
yading@10 179 img_ptr = (uint16_t*) (picture->data[0] + y*picture->linesize[0]);
yading@10 180 for (x = 0; x < picture->width; x++, index++) {
yading@10 181 for (c = 0; c < image->numcomps; c++) {
yading@10 182 *img_ptr++ = image->comps[c].data[index] << adjust[c];
yading@10 183 }
yading@10 184 }
yading@10 185 }
yading@10 186 }
yading@10 187
yading@10 188 static inline void libopenjpeg_copyto8(AVFrame *picture, opj_image_t *image) {
yading@10 189 int *comp_data;
yading@10 190 uint8_t *img_ptr;
yading@10 191 int index, x, y;
yading@10 192
yading@10 193 for (index = 0; index < image->numcomps; index++) {
yading@10 194 comp_data = image->comps[index].data;
yading@10 195 for (y = 0; y < image->comps[index].h; y++) {
yading@10 196 img_ptr = picture->data[index] + y * picture->linesize[index];
yading@10 197 for (x = 0; x < image->comps[index].w; x++) {
yading@10 198 *img_ptr = (uint8_t) *comp_data;
yading@10 199 img_ptr++;
yading@10 200 comp_data++;
yading@10 201 }
yading@10 202 }
yading@10 203 }
yading@10 204 }
yading@10 205
yading@10 206 static inline void libopenjpeg_copyto16(AVFrame *picture, opj_image_t *image) {
yading@10 207 int *comp_data;
yading@10 208 uint16_t *img_ptr;
yading@10 209 int index, x, y;
yading@10 210 for (index = 0; index < image->numcomps; index++) {
yading@10 211 comp_data = image->comps[index].data;
yading@10 212 for (y = 0; y < image->comps[index].h; y++) {
yading@10 213 img_ptr = (uint16_t*) (picture->data[index] + y * picture->linesize[index]);
yading@10 214 for (x = 0; x < image->comps[index].w; x++) {
yading@10 215 *img_ptr = *comp_data;
yading@10 216 img_ptr++;
yading@10 217 comp_data++;
yading@10 218 }
yading@10 219 }
yading@10 220 }
yading@10 221 }
yading@10 222
yading@10 223 static av_cold int libopenjpeg_decode_init(AVCodecContext *avctx)
yading@10 224 {
yading@10 225 LibOpenJPEGContext *ctx = avctx->priv_data;
yading@10 226
yading@10 227 opj_set_default_decoder_parameters(&ctx->dec_params);
yading@10 228 return 0;
yading@10 229 }
yading@10 230
yading@10 231 static int libopenjpeg_decode_frame(AVCodecContext *avctx,
yading@10 232 void *data, int *got_frame,
yading@10 233 AVPacket *avpkt)
yading@10 234 {
yading@10 235 uint8_t *buf = avpkt->data;
yading@10 236 int buf_size = avpkt->size;
yading@10 237 LibOpenJPEGContext *ctx = avctx->priv_data;
yading@10 238 ThreadFrame frame = { .f = data };
yading@10 239 AVFrame *picture = data;
yading@10 240 const AVPixFmtDescriptor *desc;
yading@10 241 opj_dinfo_t *dec;
yading@10 242 opj_cio_t *stream;
yading@10 243 opj_image_t *image;
yading@10 244 int width, height, ret = -1;
yading@10 245 int pixel_size = 0;
yading@10 246 int ispacked = 0;
yading@10 247 int i;
yading@10 248
yading@10 249 *got_frame = 0;
yading@10 250
yading@10 251 // Check if input is a raw jpeg2k codestream or in jp2 wrapping
yading@10 252 if ((AV_RB32(buf) == 12) &&
yading@10 253 (AV_RB32(buf + 4) == JP2_SIG_TYPE) &&
yading@10 254 (AV_RB32(buf + 8) == JP2_SIG_VALUE)) {
yading@10 255 dec = opj_create_decompress(CODEC_JP2);
yading@10 256 } else {
yading@10 257 /* If the AVPacket contains a jp2c box, then skip to
yading@10 258 * the starting byte of the codestream. */
yading@10 259 if (AV_RB32(buf + 4) == AV_RB32("jp2c"))
yading@10 260 buf += 8;
yading@10 261 dec = opj_create_decompress(CODEC_J2K);
yading@10 262 }
yading@10 263
yading@10 264 if (!dec) {
yading@10 265 av_log(avctx, AV_LOG_ERROR, "Error initializing decoder.\n");
yading@10 266 return -1;
yading@10 267 }
yading@10 268 opj_set_event_mgr((opj_common_ptr)dec, NULL, NULL);
yading@10 269 ctx->dec_params.cp_limit_decoding = LIMIT_TO_MAIN_HEADER;
yading@10 270 ctx->dec_params.cp_layer = ctx->lowqual;
yading@10 271 // Tie decoder with decoding parameters
yading@10 272 opj_setup_decoder(dec, &ctx->dec_params);
yading@10 273 stream = opj_cio_open((opj_common_ptr)dec, buf, buf_size);
yading@10 274
yading@10 275 if (!stream) {
yading@10 276 av_log(avctx, AV_LOG_ERROR,
yading@10 277 "Codestream could not be opened for reading.\n");
yading@10 278 opj_destroy_decompress(dec);
yading@10 279 return -1;
yading@10 280 }
yading@10 281
yading@10 282 // Decode the header only.
yading@10 283 image = opj_decode_with_info(dec, stream, NULL);
yading@10 284 opj_cio_close(stream);
yading@10 285
yading@10 286 if (!image) {
yading@10 287 av_log(avctx, AV_LOG_ERROR, "Error decoding codestream.\n");
yading@10 288 opj_destroy_decompress(dec);
yading@10 289 return -1;
yading@10 290 }
yading@10 291
yading@10 292 width = image->x1 - image->x0;
yading@10 293 height = image->y1 - image->y0;
yading@10 294
yading@10 295 if (av_image_check_size(width, height, 0, avctx) < 0) {
yading@10 296 av_log(avctx, AV_LOG_ERROR,
yading@10 297 "%dx%d dimension invalid.\n", width, height);
yading@10 298 goto done;
yading@10 299 }
yading@10 300
yading@10 301 avcodec_set_dimensions(avctx, width, height);
yading@10 302
yading@10 303 if (avctx->pix_fmt != AV_PIX_FMT_NONE)
yading@10 304 if (!libopenjpeg_matches_pix_fmt(image, avctx->pix_fmt))
yading@10 305 avctx->pix_fmt = AV_PIX_FMT_NONE;
yading@10 306
yading@10 307 if (avctx->pix_fmt == AV_PIX_FMT_NONE)
yading@10 308 avctx->pix_fmt = libopenjpeg_guess_pix_fmt(image);
yading@10 309
yading@10 310 if (avctx->pix_fmt == AV_PIX_FMT_NONE) {
yading@10 311 av_log(avctx, AV_LOG_ERROR, "Unable to determine pixel format\n");
yading@10 312 goto done;
yading@10 313 }
yading@10 314 for (i = 0; i < image->numcomps; i++)
yading@10 315 if (image->comps[i].prec > avctx->bits_per_raw_sample)
yading@10 316 avctx->bits_per_raw_sample = image->comps[i].prec;
yading@10 317
yading@10 318 if (ff_thread_get_buffer(avctx, &frame, 0) < 0)
yading@10 319 goto done;
yading@10 320
yading@10 321 ctx->dec_params.cp_limit_decoding = NO_LIMITATION;
yading@10 322 ctx->dec_params.cp_reduce = avctx->lowres;
yading@10 323 // Tie decoder with decoding parameters.
yading@10 324 opj_setup_decoder(dec, &ctx->dec_params);
yading@10 325 stream = opj_cio_open((opj_common_ptr)dec, buf, buf_size);
yading@10 326 if (!stream) {
yading@10 327 av_log(avctx, AV_LOG_ERROR,
yading@10 328 "Codestream could not be opened for reading.\n");
yading@10 329 goto done;
yading@10 330 }
yading@10 331
yading@10 332 opj_image_destroy(image);
yading@10 333 // Decode the codestream
yading@10 334 image = opj_decode_with_info(dec, stream, NULL);
yading@10 335 opj_cio_close(stream);
yading@10 336
yading@10 337 if (!image) {
yading@10 338 av_log(avctx, AV_LOG_ERROR, "Error decoding codestream.\n");
yading@10 339 goto done;
yading@10 340 }
yading@10 341
yading@10 342 desc = av_pix_fmt_desc_get(avctx->pix_fmt);
yading@10 343 pixel_size = desc->comp[0].step_minus1 + 1;
yading@10 344 ispacked = libopenjpeg_ispacked(avctx->pix_fmt);
yading@10 345
yading@10 346 switch (pixel_size) {
yading@10 347 case 1:
yading@10 348 if (ispacked) {
yading@10 349 libopenjpeg_copy_to_packed8(picture, image);
yading@10 350 } else {
yading@10 351 libopenjpeg_copyto8(picture, image);
yading@10 352 }
yading@10 353 break;
yading@10 354 case 2:
yading@10 355 if (ispacked) {
yading@10 356 libopenjpeg_copy_to_packed8(picture, image);
yading@10 357 } else {
yading@10 358 libopenjpeg_copyto16(picture, image);
yading@10 359 }
yading@10 360 break;
yading@10 361 case 3:
yading@10 362 case 4:
yading@10 363 if (ispacked) {
yading@10 364 libopenjpeg_copy_to_packed8(picture, image);
yading@10 365 }
yading@10 366 break;
yading@10 367 case 6:
yading@10 368 case 8:
yading@10 369 if (ispacked) {
yading@10 370 libopenjpeg_copy_to_packed16(picture, image);
yading@10 371 }
yading@10 372 break;
yading@10 373 default:
yading@10 374 av_log(avctx, AV_LOG_ERROR, "unsupported pixel size %d\n", pixel_size);
yading@10 375 goto done;
yading@10 376 }
yading@10 377
yading@10 378 *got_frame = 1;
yading@10 379 ret = buf_size;
yading@10 380
yading@10 381 done:
yading@10 382 opj_image_destroy(image);
yading@10 383 opj_destroy_decompress(dec);
yading@10 384 return ret;
yading@10 385 }
yading@10 386
yading@10 387 #define OFFSET(x) offsetof(LibOpenJPEGContext, x)
yading@10 388 #define VD AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
yading@10 389
yading@10 390 static const AVOption options[] = {
yading@10 391 { "lowqual", "Limit the number of layers used for decoding", OFFSET(lowqual), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, VD },
yading@10 392 { NULL },
yading@10 393 };
yading@10 394
yading@10 395 static const AVClass class = {
yading@10 396 .class_name = "libopenjpeg",
yading@10 397 .item_name = av_default_item_name,
yading@10 398 .option = options,
yading@10 399 .version = LIBAVUTIL_VERSION_INT,
yading@10 400 };
yading@10 401
yading@10 402 AVCodec ff_libopenjpeg_decoder = {
yading@10 403 .name = "libopenjpeg",
yading@10 404 .type = AVMEDIA_TYPE_VIDEO,
yading@10 405 .id = AV_CODEC_ID_JPEG2000,
yading@10 406 .priv_data_size = sizeof(LibOpenJPEGContext),
yading@10 407 .init = libopenjpeg_decode_init,
yading@10 408 .decode = libopenjpeg_decode_frame,
yading@10 409 .capabilities = CODEC_CAP_DR1 | CODEC_CAP_FRAME_THREADS,
yading@10 410 .max_lowres = 31,
yading@10 411 .long_name = NULL_IF_CONFIG_SMALL("OpenJPEG JPEG 2000"),
yading@10 412 .priv_class = &class,
yading@10 413 };