libopenjpegenc.c 30.5 KB
Newer Older
1 2
/*
 * JPEG 2000 encoding support via OpenJPEG
3
 * Copyright (c) 2011 Michael Bradshaw <mjbshaw gmail com>
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
 *
 * This file is part of FFmpeg.
 *
 * FFmpeg is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * FFmpeg is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with FFmpeg; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

/**
23 24 25
 * @file
 * JPEG 2000 encoder using libopenjpeg
 */
26

27
#include "libavutil/avassert.h"
28
#include "libavutil/common.h"
29
#include "libavutil/imgutils.h"
30
#include "libavutil/intreadwrite.h"
31
#include "libavutil/opt.h"
32
#include "avcodec.h"
33
#include "internal.h"
34

35 36 37 38 39 40
#if HAVE_OPENJPEG_2_1_OPENJPEG_H
#  include <openjpeg-2.1/openjpeg.h>
#elif HAVE_OPENJPEG_2_0_OPENJPEG_H
#  include <openjpeg-2.0/openjpeg.h>
#elif HAVE_OPENJPEG_1_5_OPENJPEG_H
#  include <openjpeg-1.5/openjpeg.h>
41
#else
42 43 44 45 46 47 48 49 50
#  include <openjpeg.h>
#endif

#if HAVE_OPENJPEG_2_1_OPENJPEG_H || HAVE_OPENJPEG_2_0_OPENJPEG_H
#  define OPENJPEG_MAJOR_VERSION 2
#  define OPJ(x) OPJ_##x
#else
#  define OPENJPEG_MAJOR_VERSION 1
#  define OPJ(x) x
51 52
#endif

53
typedef struct LibOpenJPEGContext {
54
    AVClass *avclass;
55
#if OPENJPEG_MAJOR_VERSION == 1
56
    opj_image_t *image;
57
#endif // OPENJPEG_MAJOR_VERSION == 1
58
    opj_cparameters_t enc_params;
59
#if OPENJPEG_MAJOR_VERSION == 1
60
    opj_event_mgr_t event_mgr;
61
#endif // OPENJPEG_MAJOR_VERSION == 1
62 63 64
    int format;
    int profile;
    int prog_order;
65
    int cinema_mode;
66 67 68 69 70
    int numresolution;
    int numlayers;
    int disto_alloc;
    int fixed_alloc;
    int fixed_quality;
71 72 73 74
} LibOpenJPEGContext;

static void error_callback(const char *msg, void *data)
{
75
    av_log(data, AV_LOG_ERROR, "%s\n", msg);
76 77 78 79
}

static void warning_callback(const char *msg, void *data)
{
80 81 82 83 84 85
    av_log(data, AV_LOG_WARNING, "%s\n", msg);
}

static void info_callback(const char *msg, void *data)
{
    av_log(data, AV_LOG_DEBUG, "%s\n", msg);
86 87
}

88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
#if OPENJPEG_MAJOR_VERSION == 2
typedef struct PacketWriter {
    int pos;
    AVPacket *packet;
} PacketWriter;

static OPJ_SIZE_T stream_write(void *out_buffer, OPJ_SIZE_T nb_bytes, void *user_data)
{
    PacketWriter *writer = user_data;
    AVPacket *packet = writer->packet;
    int remaining = packet->size - writer->pos;
    if (nb_bytes > remaining) {
        OPJ_SIZE_T needed = nb_bytes - remaining;
        int max_growth = INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE - packet->size;
        if (needed > max_growth) {
            return (OPJ_SIZE_T)-1;
        }
        if (av_grow_packet(packet, (int)needed)) {
            return (OPJ_SIZE_T)-1;
        }
    }
    memcpy(packet->data + writer->pos, out_buffer, nb_bytes);
    writer->pos += (int)nb_bytes;
    return nb_bytes;
}

static OPJ_OFF_T stream_skip(OPJ_OFF_T nb_bytes, void *user_data)
{
    PacketWriter *writer = user_data;
    AVPacket *packet = writer->packet;
    if (nb_bytes < 0) {
        if (writer->pos == 0) {
            return (OPJ_SIZE_T)-1;
        }
        if (nb_bytes + writer->pos < 0) {
            nb_bytes = -writer->pos;
        }
    } else {
        int remaining = packet->size - writer->pos;
        if (nb_bytes > remaining) {
            OPJ_SIZE_T needed = nb_bytes - remaining;
            int max_growth = INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE - packet->size;
            if (needed > max_growth) {
                return (OPJ_SIZE_T)-1;
            }
            if (av_grow_packet(packet, (int)needed)) {
                return (OPJ_SIZE_T)-1;
            }
        }
    }
    writer->pos += (int)nb_bytes;
    return nb_bytes;
}

static OPJ_BOOL stream_seek(OPJ_OFF_T nb_bytes, void *user_data)
{
    PacketWriter *writer = user_data;
    AVPacket *packet = writer->packet;
    if (nb_bytes < 0) {
        return OPJ_FALSE;
    }
    if (nb_bytes > packet->size) {
        if (nb_bytes > INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE ||
            av_grow_packet(packet, (int)nb_bytes - packet->size)) {
            return OPJ_FALSE;
        }
    }
    writer->pos = (int)nb_bytes;
    return OPJ_TRUE;
}
#endif // OPENJPEG_MAJOR_VERSION == 2

160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181
static void cinema_parameters(opj_cparameters_t *p)
{
    p->tile_size_on = 0;
    p->cp_tdx = 1;
    p->cp_tdy = 1;

    /* Tile part */
    p->tp_flag = 'C';
    p->tp_on = 1;

    /* Tile and Image shall be at (0, 0) */
    p->cp_tx0 = 0;
    p->cp_ty0 = 0;
    p->image_offset_x0 = 0;
    p->image_offset_y0 = 0;

    /* Codeblock size= 32 * 32 */
    p->cblockw_init = 32;
    p->cblockh_init = 32;
    p->csty |= 0x01;

    /* The progression order shall be CPRL */
182
    p->prog_order = OPJ(CPRL);
183 184 185 186 187 188 189 190 191 192 193 194 195 196

    /* No ROI */
    p->roi_compno = -1;

    /* No subsampling */
    p->subsampling_dx = 1;
    p->subsampling_dy = 1;

    /* 9-7 transform */
    p->irreversible = 1;

    p->tcp_mct = 1;
}

197 198
static opj_image_t *mj2_create_image(AVCodecContext *avctx, opj_cparameters_t *parameters)
{
199
    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt);
200
    opj_image_cmptparm_t cmptparm[4] = {{0}};
201 202 203 204
    opj_image_t *img;
    int i;
    int sub_dx[4];
    int sub_dy[4];
205
    int numcomps;
206
    OPJ_COLOR_SPACE color_space = OPJ(CLRSPC_UNKNOWN);
207

208 209
    sub_dx[0] = sub_dx[3] = 1;
    sub_dy[0] = sub_dy[3] = 1;
210 211
    sub_dx[1] = sub_dx[2] = 1 << desc->log2_chroma_w;
    sub_dy[1] = sub_dy[2] = 1 << desc->log2_chroma_h;
212

213
    numcomps = desc->nb_components;
214

215
    switch (avctx->pix_fmt) {
216
    case AV_PIX_FMT_GRAY8:
217
    case AV_PIX_FMT_YA8:
218
    case AV_PIX_FMT_GRAY16:
219
    case AV_PIX_FMT_YA16:
220
        color_space = OPJ(CLRSPC_GRAY);
221
        break;
222 223 224
    case AV_PIX_FMT_RGB24:
    case AV_PIX_FMT_RGBA:
    case AV_PIX_FMT_RGB48:
225
    case AV_PIX_FMT_RGBA64:
226 227 228 229 230 231
    case AV_PIX_FMT_GBR24P:
    case AV_PIX_FMT_GBRP9:
    case AV_PIX_FMT_GBRP10:
    case AV_PIX_FMT_GBRP12:
    case AV_PIX_FMT_GBRP14:
    case AV_PIX_FMT_GBRP16:
232
    case AV_PIX_FMT_XYZ12:
233
        color_space = OPJ(CLRSPC_SRGB);
234
        break;
235 236 237 238 239 240 241
    case AV_PIX_FMT_YUV410P:
    case AV_PIX_FMT_YUV411P:
    case AV_PIX_FMT_YUV420P:
    case AV_PIX_FMT_YUV422P:
    case AV_PIX_FMT_YUV440P:
    case AV_PIX_FMT_YUV444P:
    case AV_PIX_FMT_YUVA420P:
242 243
    case AV_PIX_FMT_YUVA422P:
    case AV_PIX_FMT_YUVA444P:
244 245 246
    case AV_PIX_FMT_YUV420P9:
    case AV_PIX_FMT_YUV422P9:
    case AV_PIX_FMT_YUV444P9:
247 248 249
    case AV_PIX_FMT_YUVA420P9:
    case AV_PIX_FMT_YUVA422P9:
    case AV_PIX_FMT_YUVA444P9:
250 251 252
    case AV_PIX_FMT_YUV420P10:
    case AV_PIX_FMT_YUV422P10:
    case AV_PIX_FMT_YUV444P10:
253 254 255
    case AV_PIX_FMT_YUVA420P10:
    case AV_PIX_FMT_YUVA422P10:
    case AV_PIX_FMT_YUVA444P10:
256 257 258 259 260 261
    case AV_PIX_FMT_YUV420P12:
    case AV_PIX_FMT_YUV422P12:
    case AV_PIX_FMT_YUV444P12:
    case AV_PIX_FMT_YUV420P14:
    case AV_PIX_FMT_YUV422P14:
    case AV_PIX_FMT_YUV444P14:
262 263 264
    case AV_PIX_FMT_YUV420P16:
    case AV_PIX_FMT_YUV422P16:
    case AV_PIX_FMT_YUV444P16:
265 266 267
    case AV_PIX_FMT_YUVA420P16:
    case AV_PIX_FMT_YUVA422P16:
    case AV_PIX_FMT_YUVA444P16:
268
        color_space = OPJ(CLRSPC_SYCC);
269 270
        break;
    default:
271 272 273
        av_log(avctx, AV_LOG_ERROR,
               "The requested pixel format '%s' is not supported\n",
               av_get_pix_fmt_name(avctx->pix_fmt));
274 275 276 277
        return NULL;
    }

    for (i = 0; i < numcomps; i++) {
278 279
        cmptparm[i].prec = desc->comp[i].depth;
        cmptparm[i].bpp  = desc->comp[i].depth;
280 281 282
        cmptparm[i].sgnd = 0;
        cmptparm[i].dx = sub_dx[i];
        cmptparm[i].dy = sub_dy[i];
283 284
        cmptparm[i].w = (avctx->width + sub_dx[i] - 1) / sub_dx[i];
        cmptparm[i].h = (avctx->height + sub_dy[i] - 1) / sub_dy[i];
285 286 287
    }

    img = opj_image_create(numcomps, cmptparm, color_space);
288

289 290 291
    if (!img)
        return NULL;

292 293 294 295 296 297 298
    // x0, y0 is the top left corner of the image
    // x1, y1 is the width, height of the reference grid
    img->x0 = 0;
    img->y0 = 0;
    img->x1 = (avctx->width  - 1) * parameters->subsampling_dx + 1;
    img->y1 = (avctx->height - 1) * parameters->subsampling_dy + 1;

299 300 301 302 303 304
    return img;
}

static av_cold int libopenjpeg_encode_init(AVCodecContext *avctx)
{
    LibOpenJPEGContext *ctx = avctx->priv_data;
305
    int err = 0;
306 307

    opj_set_default_encoder_parameters(&ctx->enc_params);
308

309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350
#if HAVE_OPENJPEG_2_1_OPENJPEG_H
    switch (ctx->cinema_mode) {
    case OPJ_CINEMA2K_24:
        ctx->enc_params.rsiz = OPJ_PROFILE_CINEMA_2K;
        ctx->enc_params.max_cs_size = OPJ_CINEMA_24_CS;
        ctx->enc_params.max_comp_size = OPJ_CINEMA_24_COMP;
        break;
    case OPJ_CINEMA2K_48:
        ctx->enc_params.rsiz = OPJ_PROFILE_CINEMA_2K;
        ctx->enc_params.max_cs_size = OPJ_CINEMA_48_CS;
        ctx->enc_params.max_comp_size = OPJ_CINEMA_48_COMP;
        break;
    case OPJ_CINEMA4K_24:
        ctx->enc_params.rsiz = OPJ_PROFILE_CINEMA_4K;
        ctx->enc_params.max_cs_size = OPJ_CINEMA_24_CS;
        ctx->enc_params.max_comp_size = OPJ_CINEMA_24_COMP;
        break;
    }

    switch (ctx->profile) {
    case OPJ_CINEMA2K:
        if (ctx->enc_params.rsiz == OPJ_PROFILE_CINEMA_4K) {
            err = AVERROR(EINVAL);
            break;
        }
        ctx->enc_params.rsiz = OPJ_PROFILE_CINEMA_2K;
        break;
    case OPJ_CINEMA4K:
        if (ctx->enc_params.rsiz == OPJ_PROFILE_CINEMA_2K) {
            err = AVERROR(EINVAL);
            break;
        }
        ctx->enc_params.rsiz = OPJ_PROFILE_CINEMA_4K;
        break;
    }

    if (err) {
        av_log(avctx, AV_LOG_ERROR,
               "Invalid parameter pairing: cinema_mode and profile conflict.\n");
        goto fail;
    }
#else
351 352
    ctx->enc_params.cp_rsiz = ctx->profile;
    ctx->enc_params.cp_cinema = ctx->cinema_mode;
353 354
#endif

355 356 357 358 359 360
    if (!ctx->numresolution) {
        ctx->numresolution = 6;
        while (FFMIN(avctx->width, avctx->height) >> ctx->numresolution < 1)
            ctx->numresolution --;
    }

361
    ctx->enc_params.mode = !!avctx->global_quality;
362 363 364 365 366 367
    ctx->enc_params.prog_order = ctx->prog_order;
    ctx->enc_params.numresolution = ctx->numresolution;
    ctx->enc_params.cp_disto_alloc = ctx->disto_alloc;
    ctx->enc_params.cp_fixed_alloc = ctx->fixed_alloc;
    ctx->enc_params.cp_fixed_quality = ctx->fixed_quality;
    ctx->enc_params.tcp_numlayers = ctx->numlayers;
368
    ctx->enc_params.tcp_rates[0] = FFMAX(avctx->compression_level, 0) * 2;
369

370
    if (ctx->cinema_mode > 0) {
371
        cinema_parameters(&ctx->enc_params);
372 373
    }

374
#if OPENJPEG_MAJOR_VERSION == 1
375 376 377
    ctx->image = mj2_create_image(avctx, &ctx->enc_params);
    if (!ctx->image) {
        av_log(avctx, AV_LOG_ERROR, "Error creating the mj2 image\n");
378 379
        err = AVERROR(EINVAL);
        goto fail;
380
    }
381
#endif // OPENJPEG_MAJOR_VERSION == 1
382

383
    return 0;
384 385

fail:
386
#if OPENJPEG_MAJOR_VERSION == 1
387 388
    opj_image_destroy(ctx->image);
    ctx->image = NULL;
389
#endif // OPENJPEG_MAJOR_VERSION == 1
390
    return err;
391 392
}

393
static int libopenjpeg_copy_packed8(AVCodecContext *avctx, const AVFrame *frame, opj_image_t *image)
394 395 396 397
{
    int compno;
    int x;
    int y;
398
    int *image_line;
399
    int frame_index;
400
    const int numcomps = image->numcomps;
401 402 403

    for (compno = 0; compno < numcomps; ++compno) {
        if (image->comps[compno].w > frame->linesize[0] / numcomps) {
404
            av_log(avctx, AV_LOG_ERROR, "Error: frame's linesize is too small for the image\n");
405 406 407 408 409 410
            return 0;
        }
    }

    for (compno = 0; compno < numcomps; ++compno) {
        for (y = 0; y < avctx->height; ++y) {
411
            image_line = image->comps[compno].data + y * image->comps[compno].w;
412
            frame_index = y * frame->linesize[0] + compno;
413
            for (x = 0; x < avctx->width; ++x) {
414
                image_line[x] = frame->data[0][frame_index];
415
                frame_index += numcomps;
416
            }
417 418 419 420 421 422 423
            for (; x < image->comps[compno].w; ++x) {
                image_line[x] = image_line[x - 1];
            }
        }
        for (; y < image->comps[compno].h; ++y) {
            image_line = image->comps[compno].data + y * image->comps[compno].w;
            for (x = 0; x < image->comps[compno].w; ++x) {
424
                image_line[x] = image_line[x - (int)image->comps[compno].w];
425
            }
426 427 428 429 430 431
        }
    }

    return 1;
}

432 433 434 435
// for XYZ 12 bit
static int libopenjpeg_copy_packed12(AVCodecContext *avctx, const AVFrame *frame, opj_image_t *image)
{
    int compno;
436
    int x, y;
437
    int *image_line;
438
    int frame_index;
439 440
    const int numcomps  = image->numcomps;
    uint16_t *frame_ptr = (uint16_t *)frame->data[0];
441 442 443 444 445 446 447 448 449 450

    for (compno = 0; compno < numcomps; ++compno) {
        if (image->comps[compno].w > frame->linesize[0] / numcomps) {
            av_log(avctx, AV_LOG_ERROR, "Error: frame's linesize is too small for the image\n");
            return 0;
        }
    }

    for (compno = 0; compno < numcomps; ++compno) {
        for (y = 0; y < avctx->height; ++y) {
451
            image_line = image->comps[compno].data + y * image->comps[compno].w;
452 453
            frame_index = y * (frame->linesize[0] / 2) + compno;
            for (x = 0; x < avctx->width; ++x) {
454
                image_line[x] = frame_ptr[frame_index] >> 4;
455 456
                frame_index += numcomps;
            }
457 458 459 460 461 462 463
            for (; x < image->comps[compno].w; ++x) {
                image_line[x] = image_line[x - 1];
            }
        }
        for (; y < image->comps[compno].h; ++y) {
            image_line = image->comps[compno].data + y * image->comps[compno].w;
            for (x = 0; x < image->comps[compno].w; ++x) {
464
                image_line[x] = image_line[x - (int)image->comps[compno].w];
465
            }
466 467 468 469 470 471
        }
    }

    return 1;
}

472
static int libopenjpeg_copy_packed16(AVCodecContext *avctx, const AVFrame *frame, opj_image_t *image)
473 474 475 476
{
    int compno;
    int x;
    int y;
477
    int *image_line;
478
    int frame_index;
479
    const int numcomps = image->numcomps;
480 481 482 483
    uint16_t *frame_ptr = (uint16_t*)frame->data[0];

    for (compno = 0; compno < numcomps; ++compno) {
        if (image->comps[compno].w > frame->linesize[0] / numcomps) {
484
            av_log(avctx, AV_LOG_ERROR, "Error: frame's linesize is too small for the image\n");
485 486 487 488 489 490
            return 0;
        }
    }

    for (compno = 0; compno < numcomps; ++compno) {
        for (y = 0; y < avctx->height; ++y) {
491
            image_line = image->comps[compno].data + y * image->comps[compno].w;
492
            frame_index = y * (frame->linesize[0] / 2) + compno;
493
            for (x = 0; x < avctx->width; ++x) {
494
                image_line[x] = frame_ptr[frame_index];
495
                frame_index += numcomps;
496
            }
497 498 499 500 501 502 503
            for (; x < image->comps[compno].w; ++x) {
                image_line[x] = image_line[x - 1];
            }
        }
        for (; y < image->comps[compno].h; ++y) {
            image_line = image->comps[compno].data + y * image->comps[compno].w;
            for (x = 0; x < image->comps[compno].w; ++x) {
504
                image_line[x] = image_line[x - (int)image->comps[compno].w];
505
            }
506 507 508 509 510 511
        }
    }

    return 1;
}

512
static int libopenjpeg_copy_unpacked8(AVCodecContext *avctx, const AVFrame *frame, opj_image_t *image)
513 514 515 516 517 518
{
    int compno;
    int x;
    int y;
    int width;
    int height;
519
    int *image_line;
520
    int frame_index;
521
    const int numcomps = image->numcomps;
522 523 524

    for (compno = 0; compno < numcomps; ++compno) {
        if (image->comps[compno].w > frame->linesize[compno]) {
525
            av_log(avctx, AV_LOG_ERROR, "Error: frame's linesize is too small for the image\n");
526 527 528 529 530
            return 0;
        }
    }

    for (compno = 0; compno < numcomps; ++compno) {
531 532
        width  = (avctx->width + image->comps[compno].dx - 1) / image->comps[compno].dx;
        height = (avctx->height + image->comps[compno].dy - 1) / image->comps[compno].dy;
533
        for (y = 0; y < height; ++y) {
534
            image_line = image->comps[compno].data + y * image->comps[compno].w;
535
            frame_index = y * frame->linesize[compno];
536
            for (x = 0; x < width; ++x)
537 538 539 540 541 542 543 544
                image_line[x] = frame->data[compno][frame_index++];
            for (; x < image->comps[compno].w; ++x) {
                image_line[x] = image_line[x - 1];
            }
        }
        for (; y < image->comps[compno].h; ++y) {
            image_line = image->comps[compno].data + y * image->comps[compno].w;
            for (x = 0; x < image->comps[compno].w; ++x) {
545
                image_line[x] = image_line[x - (int)image->comps[compno].w];
546
            }
547 548 549 550 551 552
        }
    }

    return 1;
}

553
static int libopenjpeg_copy_unpacked16(AVCodecContext *avctx, const AVFrame *frame, opj_image_t *image)
554 555 556 557 558 559
{
    int compno;
    int x;
    int y;
    int width;
    int height;
560
    int *image_line;
561
    int frame_index;
562
    const int numcomps = image->numcomps;
563 564 565 566
    uint16_t *frame_ptr;

    for (compno = 0; compno < numcomps; ++compno) {
        if (image->comps[compno].w > frame->linesize[compno]) {
567
            av_log(avctx, AV_LOG_ERROR, "Error: frame's linesize is too small for the image\n");
568 569 570 571 572
            return 0;
        }
    }

    for (compno = 0; compno < numcomps; ++compno) {
573 574
        width     = (avctx->width + image->comps[compno].dx - 1) / image->comps[compno].dx;
        height    = (avctx->height + image->comps[compno].dy - 1) / image->comps[compno].dy;
575
        frame_ptr = (uint16_t *)frame->data[compno];
576
        for (y = 0; y < height; ++y) {
577
            image_line = image->comps[compno].data + y * image->comps[compno].w;
578
            frame_index = y * (frame->linesize[compno] / 2);
579
            for (x = 0; x < width; ++x)
580 581 582 583 584 585 586 587
                image_line[x] = frame_ptr[frame_index++];
            for (; x < image->comps[compno].w; ++x) {
                image_line[x] = image_line[x - 1];
            }
        }
        for (; y < image->comps[compno].h; ++y) {
            image_line = image->comps[compno].data + y * image->comps[compno].w;
            for (x = 0; x < image->comps[compno].w; ++x) {
588
                image_line[x] = image_line[x - (int)image->comps[compno].w];
589
            }
590 591 592 593 594 595
        }
    }

    return 1;
}

596 597
static int libopenjpeg_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
                                    const AVFrame *frame, int *got_packet)
598 599
{
    LibOpenJPEGContext *ctx = avctx->priv_data;
600 601 602
    int ret;
    AVFrame *gbrframe;
    int cpyresult = 0;
603
#if OPENJPEG_MAJOR_VERSION == 1
604
    opj_image_t *image      = ctx->image;
605 606
    opj_cinfo_t *compress   = NULL;
    opj_cio_t *stream       = NULL;
607 608
    int len;
#else // OPENJPEG_MAJOR_VERSION == 2
609
    PacketWriter writer     = { 0 };
610 611
    opj_codec_t *compress   = NULL;
    opj_stream_t *stream    = NULL;
612 613 614 615 616 617
    opj_image_t *image      = mj2_create_image(avctx, &ctx->enc_params);
    if (!image) {
        av_log(avctx, AV_LOG_ERROR, "Error creating the mj2 image\n");
        ret = AVERROR(EINVAL);
        goto done;
    }
618
#endif // OPENJPEG_MAJOR_VERSION == 1
619 620

    switch (avctx->pix_fmt) {
621 622
    case AV_PIX_FMT_RGB24:
    case AV_PIX_FMT_RGBA:
623
    case AV_PIX_FMT_YA8:
624
        cpyresult = libopenjpeg_copy_packed8(avctx, frame, image);
625
        break;
626 627 628
    case AV_PIX_FMT_XYZ12:
        cpyresult = libopenjpeg_copy_packed12(avctx, frame, image);
        break;
629
    case AV_PIX_FMT_RGB48:
630
    case AV_PIX_FMT_RGBA64:
631
    case AV_PIX_FMT_YA16:
632
        cpyresult = libopenjpeg_copy_packed16(avctx, frame, image);
633
        break;
634 635 636 637 638 639
    case AV_PIX_FMT_GBR24P:
    case AV_PIX_FMT_GBRP9:
    case AV_PIX_FMT_GBRP10:
    case AV_PIX_FMT_GBRP12:
    case AV_PIX_FMT_GBRP14:
    case AV_PIX_FMT_GBRP16:
640
        gbrframe = av_frame_clone(frame);
641 642 643 644
        if (!gbrframe) {
            ret = AVERROR(ENOMEM);
            goto done;
        }
645 646 647 648 649 650
        gbrframe->data[0] = frame->data[2]; // swap to be rgb
        gbrframe->data[1] = frame->data[0];
        gbrframe->data[2] = frame->data[1];
        gbrframe->linesize[0] = frame->linesize[2];
        gbrframe->linesize[1] = frame->linesize[0];
        gbrframe->linesize[2] = frame->linesize[1];
651
        if (avctx->pix_fmt == AV_PIX_FMT_GBR24P) {
652
            cpyresult = libopenjpeg_copy_unpacked8(avctx, gbrframe, image);
653
        } else {
654
            cpyresult = libopenjpeg_copy_unpacked16(avctx, gbrframe, image);
655
        }
656
        av_frame_free(&gbrframe);
657
        break;
658 659 660 661 662 663 664 665
    case AV_PIX_FMT_GRAY8:
    case AV_PIX_FMT_YUV410P:
    case AV_PIX_FMT_YUV411P:
    case AV_PIX_FMT_YUV420P:
    case AV_PIX_FMT_YUV422P:
    case AV_PIX_FMT_YUV440P:
    case AV_PIX_FMT_YUV444P:
    case AV_PIX_FMT_YUVA420P:
666 667
    case AV_PIX_FMT_YUVA422P:
    case AV_PIX_FMT_YUVA444P:
668
        cpyresult = libopenjpeg_copy_unpacked8(avctx, frame, image);
669
        break;
670 671 672 673
    case AV_PIX_FMT_GRAY16:
    case AV_PIX_FMT_YUV420P9:
    case AV_PIX_FMT_YUV422P9:
    case AV_PIX_FMT_YUV444P9:
674 675 676
    case AV_PIX_FMT_YUVA420P9:
    case AV_PIX_FMT_YUVA422P9:
    case AV_PIX_FMT_YUVA444P9:
677 678 679
    case AV_PIX_FMT_YUV444P10:
    case AV_PIX_FMT_YUV422P10:
    case AV_PIX_FMT_YUV420P10:
680 681 682
    case AV_PIX_FMT_YUVA444P10:
    case AV_PIX_FMT_YUVA422P10:
    case AV_PIX_FMT_YUVA420P10:
683 684 685 686 687 688
    case AV_PIX_FMT_YUV420P12:
    case AV_PIX_FMT_YUV422P12:
    case AV_PIX_FMT_YUV444P12:
    case AV_PIX_FMT_YUV420P14:
    case AV_PIX_FMT_YUV422P14:
    case AV_PIX_FMT_YUV444P14:
689 690 691
    case AV_PIX_FMT_YUV444P16:
    case AV_PIX_FMT_YUV422P16:
    case AV_PIX_FMT_YUV420P16:
692 693 694
    case AV_PIX_FMT_YUVA444P16:
    case AV_PIX_FMT_YUVA422P16:
    case AV_PIX_FMT_YUVA420P16:
695
        cpyresult = libopenjpeg_copy_unpacked16(avctx, frame, image);
696 697
        break;
    default:
698 699 700
        av_log(avctx, AV_LOG_ERROR,
               "The frame's pixel format '%s' is not supported\n",
               av_get_pix_fmt_name(avctx->pix_fmt));
701 702
        ret = AVERROR(EINVAL);
        goto done;
703 704 705 706
        break;
    }

    if (!cpyresult) {
707 708
        av_log(avctx, AV_LOG_ERROR,
               "Could not copy the frame data to the internal image buffer\n");
709 710
        ret = -1;
        goto done;
711 712
    }

713 714
#if OPENJPEG_MAJOR_VERSION == 2
    if ((ret = ff_alloc_packet2(avctx, pkt, 1024, 0)) < 0) {
715
        goto done;
716 717 718
    }
#endif // OPENJPEG_MAJOR_VERSION == 2

719 720 721
    compress = opj_create_compress(ctx->format);
    if (!compress) {
        av_log(avctx, AV_LOG_ERROR, "Error creating the compressor\n");
722 723
        ret = AVERROR(ENOMEM);
        goto done;
724 725
    }

726
#if OPENJPEG_MAJOR_VERSION == 1
727 728
    opj_setup_encoder(compress, &ctx->enc_params, image);
    stream = opj_cio_open((opj_common_ptr) compress, NULL, 0);
729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745
#else // OPENJPEG_MAJOR_VERSION == 2
    if (!opj_set_error_handler(compress, error_callback, avctx) ||
        !opj_set_warning_handler(compress, warning_callback, avctx) ||
        !opj_set_info_handler(compress, info_callback, avctx)) {
        av_log(avctx, AV_LOG_ERROR, "Error setting the compressor handlers\n");
        ret = AVERROR_EXTERNAL;
        goto done;
    }

    if (!opj_setup_encoder(compress, &ctx->enc_params, image)) {
        av_log(avctx, AV_LOG_ERROR, "Error setting up the compressor\n");
        ret = AVERROR_EXTERNAL;
        goto done;
    }
    stream = opj_stream_default_create(OPJ_STREAM_WRITE);
#endif // OPENJPEG_MAJOR_VERSION == 1

746 747
    if (!stream) {
        av_log(avctx, AV_LOG_ERROR, "Error creating the cio stream\n");
748 749
        ret = AVERROR(ENOMEM);
        goto done;
750
    }
751
#if OPENJPEG_MAJOR_VERSION == 1
752
    memset(&ctx->event_mgr, 0, sizeof(ctx->event_mgr));
753 754 755 756
    ctx->event_mgr.info_handler    = info_callback;
    ctx->event_mgr.error_handler   = error_callback;
    ctx->event_mgr.warning_handler = warning_callback;
    opj_set_event_mgr((opj_common_ptr) compress, &ctx->event_mgr, avctx);
757 758
    if (!opj_encode(compress, stream, image, NULL)) {
        av_log(avctx, AV_LOG_ERROR, "Error during the opj encode\n");
759 760
        ret = AVERROR_EXTERNAL;
        goto done;
761 762 763
    }

    len = cio_tell(stream);
764
    if ((ret = ff_alloc_packet2(avctx, pkt, len, 0)) < 0) {
765
        goto done;
766 767
    }

768
    memcpy(pkt->data, stream->buffer, len);
769
#else // OPENJPEG_MAJOR_VERSION == 2
770
    writer.packet = pkt;
771 772 773 774 775 776 777 778 779 780 781
    opj_stream_set_write_function(stream, stream_write);
    opj_stream_set_skip_function(stream, stream_skip);
    opj_stream_set_seek_function(stream, stream_seek);
#if HAVE_OPENJPEG_2_1_OPENJPEG_H
    opj_stream_set_user_data(stream, &writer, NULL);
#elif HAVE_OPENJPEG_2_0_OPENJPEG_H
    opj_stream_set_user_data(stream, &writer);
#else
#error Missing call to opj_stream_set_user_data
#endif

782
    if (!opj_start_compress(compress, image, stream) ||
783 784 785 786 787 788 789 790 791 792
        !opj_encode(compress, stream) ||
        !opj_end_compress(compress, stream)) {
        av_log(avctx, AV_LOG_ERROR, "Error during the opj encode\n");
        ret = AVERROR_EXTERNAL;
        goto done;
    }

    av_shrink_packet(pkt, writer.pos);
#endif // OPENJPEG_MAJOR_VERSION == 1

793 794
    pkt->flags |= AV_PKT_FLAG_KEY;
    *got_packet = 1;
795
    ret = 0;
796

797 798 799 800
done:
#if OPENJPEG_MAJOR_VERSION == 2
    opj_stream_destroy(stream);
    opj_destroy_codec(compress);
801
    opj_image_destroy(image);
802
#else
803 804
    opj_cio_close(stream);
    opj_destroy_compress(compress);
805 806
#endif
    return ret;
807 808 809 810
}

static av_cold int libopenjpeg_encode_close(AVCodecContext *avctx)
{
811
#if OPENJPEG_MAJOR_VERSION == 1
812 813 814
    LibOpenJPEGContext *ctx = avctx->priv_data;

    opj_image_destroy(ctx->image);
815
    ctx->image = NULL;
816
#endif // OPENJPEG_MAJOR_VERSION == 1
817
    return 0;
818 819
}

820 821 822
#define OFFSET(x) offsetof(LibOpenJPEGContext, x)
#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
static const AVOption options[] = {
823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840
    { "format",        "Codec Format",      OFFSET(format),        AV_OPT_TYPE_INT,   { .i64 = OPJ(CODEC_JP2)   }, OPJ(CODEC_J2K), OPJ(CODEC_JP2),   VE, "format"      },
    { "j2k",           NULL,                0,                     AV_OPT_TYPE_CONST, { .i64 = OPJ(CODEC_J2K)   }, 0,         0,           VE, "format"      },
    { "jp2",           NULL,                0,                     AV_OPT_TYPE_CONST, { .i64 = OPJ(CODEC_JP2)   }, 0,         0,           VE, "format"      },
    { "profile",       NULL,                OFFSET(profile),       AV_OPT_TYPE_INT,   { .i64 = OPJ(STD_RSIZ)    }, OPJ(STD_RSIZ),  OPJ(CINEMA4K),    VE, "profile"     },
    { "jpeg2000",      NULL,                0,                     AV_OPT_TYPE_CONST, { .i64 = OPJ(STD_RSIZ)    }, 0,         0,           VE, "profile"     },
    { "cinema2k",      NULL,                0,                     AV_OPT_TYPE_CONST, { .i64 = OPJ(CINEMA2K)    }, 0,         0,           VE, "profile"     },
    { "cinema4k",      NULL,                0,                     AV_OPT_TYPE_CONST, { .i64 = OPJ(CINEMA4K)    }, 0,         0,           VE, "profile"     },
    { "cinema_mode",   "Digital Cinema",    OFFSET(cinema_mode),   AV_OPT_TYPE_INT,   { .i64 = OPJ(OFF)         }, OPJ(OFF),       OPJ(CINEMA4K_24), VE, "cinema_mode" },
    { "off",           NULL,                0,                     AV_OPT_TYPE_CONST, { .i64 = OPJ(OFF)         }, 0,         0,           VE, "cinema_mode" },
    { "2k_24",         NULL,                0,                     AV_OPT_TYPE_CONST, { .i64 = OPJ(CINEMA2K_24) }, 0,         0,           VE, "cinema_mode" },
    { "2k_48",         NULL,                0,                     AV_OPT_TYPE_CONST, { .i64 = OPJ(CINEMA2K_48) }, 0,         0,           VE, "cinema_mode" },
    { "4k_24",         NULL,                0,                     AV_OPT_TYPE_CONST, { .i64 = OPJ(CINEMA4K_24) }, 0,         0,           VE, "cinema_mode" },
    { "prog_order",    "Progression Order", OFFSET(prog_order),    AV_OPT_TYPE_INT,   { .i64 = OPJ(LRCP)    }, OPJ(LRCP),  OPJ(CPRL),    VE, "prog_order"  },
    { "lrcp",          NULL,                0,                     AV_OPT_TYPE_CONST, { .i64 = OPJ(LRCP)    }, 0,         0,           VE, "prog_order"  },
    { "rlcp",          NULL,                0,                     AV_OPT_TYPE_CONST, { .i64 = OPJ(RLCP)    }, 0,         0,           VE, "prog_order"  },
    { "rpcl",          NULL,                0,                     AV_OPT_TYPE_CONST, { .i64 = OPJ(RPCL)    }, 0,         0,           VE, "prog_order"  },
    { "pcrl",          NULL,                0,                     AV_OPT_TYPE_CONST, { .i64 = OPJ(PCRL)    }, 0,         0,           VE, "prog_order"  },
    { "cprl",          NULL,                0,                     AV_OPT_TYPE_CONST, { .i64 = OPJ(CPRL)    }, 0,         0,           VE, "prog_order"  },
841
    { "numresolution", NULL,                OFFSET(numresolution), AV_OPT_TYPE_INT,   { .i64 = 0           }, 0,         INT_MAX,     VE                },
842 843 844 845
    { "numlayers",     NULL,                OFFSET(numlayers),     AV_OPT_TYPE_INT,   { .i64 = 1           }, 1,         10,          VE                },
    { "disto_alloc",   NULL,                OFFSET(disto_alloc),   AV_OPT_TYPE_INT,   { .i64 = 1           }, 0,         1,           VE                },
    { "fixed_alloc",   NULL,                OFFSET(fixed_alloc),   AV_OPT_TYPE_INT,   { .i64 = 0           }, 0,         1,           VE                },
    { "fixed_quality", NULL,                OFFSET(fixed_quality), AV_OPT_TYPE_INT,   { .i64 = 0           }, 0,         1,           VE                },
846 847 848
    { NULL },
};

849
static const AVClass openjpeg_class = {
850 851 852 853 854
    .class_name = "libopenjpeg",
    .item_name  = av_default_item_name,
    .option     = options,
    .version    = LIBAVUTIL_VERSION_INT,
};
855 856

AVCodec ff_libopenjpeg_encoder = {
857
    .name           = "libopenjpeg",
858
    .long_name      = NULL_IF_CONFIG_SMALL("OpenJPEG JPEG 2000"),
859
    .type           = AVMEDIA_TYPE_VIDEO,
860
    .id             = AV_CODEC_ID_JPEG2000,
861
    .priv_data_size = sizeof(LibOpenJPEGContext),
862
    .init           = libopenjpeg_encode_init,
863
    .encode2        = libopenjpeg_encode_frame,
864
    .close          = libopenjpeg_encode_close,
865
    .capabilities   = AV_CODEC_CAP_FRAME_THREADS | AV_CODEC_CAP_INTRA_ONLY,
866 867
    .pix_fmts       = (const enum AVPixelFormat[]) {
        AV_PIX_FMT_RGB24, AV_PIX_FMT_RGBA, AV_PIX_FMT_RGB48,
868
        AV_PIX_FMT_RGBA64, AV_PIX_FMT_GBR24P,
869
        AV_PIX_FMT_GBRP9, AV_PIX_FMT_GBRP10, AV_PIX_FMT_GBRP12, AV_PIX_FMT_GBRP14, AV_PIX_FMT_GBRP16,
870
        AV_PIX_FMT_GRAY8, AV_PIX_FMT_YA8, AV_PIX_FMT_GRAY16, AV_PIX_FMT_YA16,
871
        AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUVA420P,
872 873
        AV_PIX_FMT_YUV440P, AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUVA422P,
        AV_PIX_FMT_YUV411P, AV_PIX_FMT_YUV410P, AV_PIX_FMT_YUVA444P,
874
        AV_PIX_FMT_YUV420P9, AV_PIX_FMT_YUV422P9, AV_PIX_FMT_YUV444P9,
875
        AV_PIX_FMT_YUVA420P9, AV_PIX_FMT_YUVA422P9, AV_PIX_FMT_YUVA444P9,
876
        AV_PIX_FMT_YUV420P10, AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUV444P10,
877
        AV_PIX_FMT_YUVA420P10, AV_PIX_FMT_YUVA422P10, AV_PIX_FMT_YUVA444P10,
878 879
        AV_PIX_FMT_YUV420P12, AV_PIX_FMT_YUV422P12, AV_PIX_FMT_YUV444P12,
        AV_PIX_FMT_YUV420P14, AV_PIX_FMT_YUV422P14, AV_PIX_FMT_YUV444P14,
880
        AV_PIX_FMT_YUV420P16, AV_PIX_FMT_YUV422P16, AV_PIX_FMT_YUV444P16,
881
        AV_PIX_FMT_YUVA420P16, AV_PIX_FMT_YUVA422P16, AV_PIX_FMT_YUVA444P16,
882
        AV_PIX_FMT_XYZ12,
883
        AV_PIX_FMT_NONE
884
    },
885
    .priv_class     = &openjpeg_class,
886
};