libopenjpegenc.c 24.3 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 28
#define  OPJ_STATIC

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

37 38 39 40 41 42
#if HAVE_OPENJPEG_1_5_OPENJPEG_H
# include <openjpeg-1.5/openjpeg.h>
#else
# include <openjpeg.h>
#endif

43
typedef struct {
44
    AVClass *avclass;
45
    opj_image_t *image;
46
    opj_cio_t *stream;
47 48 49
    opj_cparameters_t enc_params;
    opj_cinfo_t *compress;
    opj_event_mgr_t event_mgr;
50 51 52
    int format;
    int profile;
    int prog_order;
53
    int cinema_mode;
54 55 56 57 58
    int numresolution;
    int numlayers;
    int disto_alloc;
    int fixed_alloc;
    int fixed_quality;
59 60 61 62
} LibOpenJPEGContext;

static void error_callback(const char *msg, void *data)
{
63
    av_log(data, AV_LOG_ERROR, "%s\n", msg);
64 65 66 67
}

static void warning_callback(const char *msg, void *data)
{
68 69 70 71 72 73
    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);
74 75 76 77
}

static opj_image_t *mj2_create_image(AVCodecContext *avctx, opj_cparameters_t *parameters)
{
78
    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt);
79
    opj_image_cmptparm_t cmptparm[4] = {{0}};
80 81 82 83
    opj_image_t *img;
    int i;
    int sub_dx[4];
    int sub_dy[4];
84
    int numcomps;
85 86
    OPJ_COLOR_SPACE color_space = CLRSPC_UNKNOWN;

87 88
    sub_dx[0] = sub_dx[3] = 1;
    sub_dy[0] = sub_dy[3] = 1;
89 90
    sub_dx[1] = sub_dx[2] = 1 << desc->log2_chroma_w;
    sub_dy[1] = sub_dy[2] = 1 << desc->log2_chroma_h;
91

92
    numcomps = desc->nb_components;
93

94
    switch (avctx->pix_fmt) {
95
    case AV_PIX_FMT_GRAY8:
96
    case AV_PIX_FMT_GRAY8A:
97
    case AV_PIX_FMT_GRAY16:
98 99
        color_space = CLRSPC_GRAY;
        break;
100 101 102
    case AV_PIX_FMT_RGB24:
    case AV_PIX_FMT_RGBA:
    case AV_PIX_FMT_RGB48:
103
    case AV_PIX_FMT_RGBA64:
104 105 106 107 108 109
    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:
110
    case AV_PIX_FMT_XYZ12:
111 112
        color_space = CLRSPC_SRGB;
        break;
113 114 115 116 117 118 119
    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:
120 121
    case AV_PIX_FMT_YUVA422P:
    case AV_PIX_FMT_YUVA444P:
122 123 124
    case AV_PIX_FMT_YUV420P9:
    case AV_PIX_FMT_YUV422P9:
    case AV_PIX_FMT_YUV444P9:
125 126 127
    case AV_PIX_FMT_YUVA420P9:
    case AV_PIX_FMT_YUVA422P9:
    case AV_PIX_FMT_YUVA444P9:
128 129 130
    case AV_PIX_FMT_YUV420P10:
    case AV_PIX_FMT_YUV422P10:
    case AV_PIX_FMT_YUV444P10:
131 132 133
    case AV_PIX_FMT_YUVA420P10:
    case AV_PIX_FMT_YUVA422P10:
    case AV_PIX_FMT_YUVA444P10:
134 135 136 137 138 139
    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:
140 141 142
    case AV_PIX_FMT_YUV420P16:
    case AV_PIX_FMT_YUV422P16:
    case AV_PIX_FMT_YUV444P16:
143 144 145
    case AV_PIX_FMT_YUVA420P16:
    case AV_PIX_FMT_YUVA422P16:
    case AV_PIX_FMT_YUVA444P16:
146
        color_space = CLRSPC_SYCC;
147 148
        break;
    default:
149 150 151
        av_log(avctx, AV_LOG_ERROR,
               "The requested pixel format '%s' is not supported\n",
               av_get_pix_fmt_name(avctx->pix_fmt));
152 153 154 155
        return NULL;
    }

    for (i = 0; i < numcomps; i++) {
156 157
        cmptparm[i].prec = desc->comp[i].depth_minus1 + 1;
        cmptparm[i].bpp  = desc->comp[i].depth_minus1 + 1;
158 159 160
        cmptparm[i].sgnd = 0;
        cmptparm[i].dx = sub_dx[i];
        cmptparm[i].dy = sub_dy[i];
161 162
        cmptparm[i].w = (avctx->width + sub_dx[i] - 1) / sub_dx[i];
        cmptparm[i].h = (avctx->height + sub_dy[i] - 1) / sub_dy[i];
163 164 165
    }

    img = opj_image_create(numcomps, cmptparm, color_space);
166 167 168 169 170 171 172 173

    // 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;

174 175 176 177 178 179
    return img;
}

static av_cold int libopenjpeg_encode_init(AVCodecContext *avctx)
{
    LibOpenJPEGContext *ctx = avctx->priv_data;
180
    int err = AVERROR(ENOMEM);
181 182

    opj_set_default_encoder_parameters(&ctx->enc_params);
183

184 185 186 187 188 189 190 191 192
    ctx->enc_params.cp_rsiz = ctx->profile;
    ctx->enc_params.mode = !!avctx->global_quality;
    ctx->enc_params.cp_cinema = ctx->cinema_mode;
    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;
193
    ctx->enc_params.tcp_rates[0] = FFMAX(avctx->compression_level, 0) * 2;
194

195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223
    if (ctx->cinema_mode > 0) {
        ctx->enc_params.irreversible = 1;
        ctx->enc_params.tcp_mct = 1;
        ctx->enc_params.tile_size_on = 0;
        /* no subsampling */
        ctx->enc_params.cp_tdx=1;
        ctx->enc_params.cp_tdy=1;
        ctx->enc_params.subsampling_dx = 1;
        ctx->enc_params.subsampling_dy = 1;
        /* Tile and Image shall be at (0,0) */
        ctx->enc_params.cp_tx0 = 0;
        ctx->enc_params.cp_ty0 = 0;
        ctx->enc_params.image_offset_x0 = 0;
        ctx->enc_params.image_offset_y0 = 0;
        /* Codeblock size= 32*32 */
        ctx->enc_params.cblockw_init = 32;
        ctx->enc_params.cblockh_init = 32;
        ctx->enc_params.csty |= 0x01;
        /* No ROI */
        ctx->enc_params.roi_compno = -1;

        if (ctx->enc_params.prog_order != CPRL) {
            av_log(avctx, AV_LOG_ERROR, "prog_order forced to CPRL\n");
            ctx->enc_params.prog_order = CPRL;
        }
        ctx->enc_params.tp_flag = 'C';
        ctx->enc_params.tp_on = 1;
    }

224
    ctx->compress = opj_create_compress(ctx->format);
225 226 227 228 229 230 231 232
    if (!ctx->compress) {
        av_log(avctx, AV_LOG_ERROR, "Error creating the compressor\n");
        return AVERROR(ENOMEM);
    }

    ctx->image = mj2_create_image(avctx, &ctx->enc_params);
    if (!ctx->image) {
        av_log(avctx, AV_LOG_ERROR, "Error creating the mj2 image\n");
233 234
        err = AVERROR(EINVAL);
        goto fail;
235
    }
236 237 238 239 240 241 242 243 244
    opj_setup_encoder(ctx->compress, &ctx->enc_params, ctx->image);

    ctx->stream = opj_cio_open((opj_common_ptr)ctx->compress, NULL, 0);
    if (!ctx->stream) {
        av_log(avctx, AV_LOG_ERROR, "Error creating the cio stream\n");
        err = AVERROR(ENOMEM);
        goto fail;
    }

245
    avctx->coded_frame = av_frame_alloc();
246 247 248 249
    if (!avctx->coded_frame) {
        av_log(avctx, AV_LOG_ERROR, "Error allocating coded frame\n");
        goto fail;
    }
250 251

    memset(&ctx->event_mgr, 0, sizeof(opj_event_mgr_t));
252
    ctx->event_mgr.info_handler    = info_callback;
253 254 255 256 257
    ctx->event_mgr.error_handler = error_callback;
    ctx->event_mgr.warning_handler = warning_callback;
    opj_set_event_mgr((opj_common_ptr)ctx->compress, &ctx->event_mgr, avctx);

    return 0;
258 259

fail:
260 261 262 263 264 265
    opj_cio_close(ctx->stream);
    ctx->stream = NULL;
    opj_destroy_compress(ctx->compress);
    ctx->compress = NULL;
    opj_image_destroy(ctx->image);
    ctx->image = NULL;
266 267
    av_freep(&avctx->coded_frame);
    return err;
268 269
}

270
static int libopenjpeg_copy_packed8(AVCodecContext *avctx, const AVFrame *frame, opj_image_t *image)
271 272 273 274
{
    int compno;
    int x;
    int y;
275
    int *image_line;
276
    int frame_index;
277
    const int numcomps = image->numcomps;
278 279 280

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

    for (compno = 0; compno < numcomps; ++compno) {
        for (y = 0; y < avctx->height; ++y) {
288
            image_line = image->comps[compno].data + y * image->comps[compno].w;
289
            frame_index = y * frame->linesize[0] + compno;
290
            for (x = 0; x < avctx->width; ++x) {
291
                image_line[x] = frame->data[0][frame_index];
292
                frame_index += numcomps;
293
            }
294 295 296 297 298 299 300 301 302
            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) {
                image_line[x] = image_line[x - image->comps[compno].w];
            }
303 304 305 306 307 308
        }
    }

    return 1;
}

309 310 311 312 313 314
// for XYZ 12 bit
static int libopenjpeg_copy_packed12(AVCodecContext *avctx, const AVFrame *frame, opj_image_t *image)
{
    int compno;
    int x;
    int y;
315
    int *image_line;
316 317 318 319 320 321 322 323 324 325 326 327 328
    int frame_index;
    const int numcomps = image->numcomps;
    uint16_t *frame_ptr = (uint16_t*)frame->data[0];

    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) {
329
            image_line = image->comps[compno].data + y * image->comps[compno].w;
330 331
            frame_index = y * (frame->linesize[0] / 2) + compno;
            for (x = 0; x < avctx->width; ++x) {
332
                image_line[x] = frame_ptr[frame_index] >> 4;
333 334
                frame_index += numcomps;
            }
335 336 337 338 339 340 341 342 343
            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) {
                image_line[x] = image_line[x - image->comps[compno].w];
            }
344 345 346 347 348 349
        }
    }

    return 1;
}

350
static int libopenjpeg_copy_packed16(AVCodecContext *avctx, const AVFrame *frame, opj_image_t *image)
351 352 353 354
{
    int compno;
    int x;
    int y;
355
    int *image_line;
356
    int frame_index;
357
    const int numcomps = image->numcomps;
358 359 360 361
    uint16_t *frame_ptr = (uint16_t*)frame->data[0];

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

    for (compno = 0; compno < numcomps; ++compno) {
        for (y = 0; y < avctx->height; ++y) {
369
            image_line = image->comps[compno].data + y * image->comps[compno].w;
370
            frame_index = y * (frame->linesize[0] / 2) + compno;
371
            for (x = 0; x < avctx->width; ++x) {
372
                image_line[x] = frame_ptr[frame_index];
373
                frame_index += numcomps;
374
            }
375 376 377 378 379 380 381 382 383
            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) {
                image_line[x] = image_line[x - image->comps[compno].w];
            }
384 385 386 387 388 389
        }
    }

    return 1;
}

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

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

    for (compno = 0; compno < numcomps; ++compno) {
        width = avctx->width / image->comps[compno].dx;
        height = avctx->height / image->comps[compno].dy;
        for (y = 0; y < height; ++y) {
412
            image_line = image->comps[compno].data + y * image->comps[compno].w;
413
            frame_index = y * frame->linesize[compno];
414
            for (x = 0; x < width; ++x)
415 416 417 418 419 420 421 422 423 424
                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) {
                image_line[x] = image_line[x - image->comps[compno].w];
            }
425 426 427 428 429 430
        }
    }

    return 1;
}

431
static int libopenjpeg_copy_unpacked16(AVCodecContext *avctx, const AVFrame *frame, opj_image_t *image)
432 433 434 435 436 437
{
    int compno;
    int x;
    int y;
    int width;
    int height;
438
    int *image_line;
439
    int frame_index;
440
    const int numcomps = image->numcomps;
441 442 443 444
    uint16_t *frame_ptr;

    for (compno = 0; compno < numcomps; ++compno) {
        if (image->comps[compno].w > frame->linesize[compno]) {
445
            av_log(avctx, AV_LOG_ERROR, "Error: frame's linesize is too small for the image\n");
446 447 448 449 450 451 452 453 454
            return 0;
        }
    }

    for (compno = 0; compno < numcomps; ++compno) {
        width = avctx->width / image->comps[compno].dx;
        height = avctx->height / image->comps[compno].dy;
        frame_ptr = (uint16_t*)frame->data[compno];
        for (y = 0; y < height; ++y) {
455
            image_line = image->comps[compno].data + y * image->comps[compno].w;
456
            frame_index = y * (frame->linesize[compno] / 2);
457
            for (x = 0; x < width; ++x)
458 459 460 461 462 463 464 465 466 467
                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) {
                image_line[x] = image_line[x - image->comps[compno].w];
            }
468 469 470 471 472 473
        }
    }

    return 1;
}

474 475
static int libopenjpeg_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
                                    const AVFrame *frame, int *got_packet)
476 477 478
{
    LibOpenJPEGContext *ctx = avctx->priv_data;
    opj_cinfo_t *compress = ctx->compress;
479
    opj_image_t *image    = ctx->image;
480
    opj_cio_t *stream     = ctx->stream;
481
    int cpyresult = 0;
482
    int ret, len;
483
    AVFrame *gbrframe;
484 485

    switch (avctx->pix_fmt) {
486 487
    case AV_PIX_FMT_RGB24:
    case AV_PIX_FMT_RGBA:
488
    case AV_PIX_FMT_GRAY8A:
489
        cpyresult = libopenjpeg_copy_packed8(avctx, frame, image);
490
        break;
491 492 493
    case AV_PIX_FMT_XYZ12:
        cpyresult = libopenjpeg_copy_packed12(avctx, frame, image);
        break;
494
    case AV_PIX_FMT_RGB48:
495
    case AV_PIX_FMT_RGBA64:
496
        cpyresult = libopenjpeg_copy_packed16(avctx, frame, image);
497
        break;
498 499 500 501 502 503
    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:
504 505 506 507 508 509 510 511
        gbrframe = av_frame_alloc();
        av_frame_ref(gbrframe, frame);
        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];
512
        if (avctx->pix_fmt == AV_PIX_FMT_GBR24P) {
513
            cpyresult = libopenjpeg_copy_unpacked8(avctx, gbrframe, image);
514
        } else {
515
            cpyresult = libopenjpeg_copy_unpacked16(avctx, gbrframe, image);
516
        }
517
        av_frame_free(&gbrframe);
518
        break;
519 520 521 522 523 524 525 526
    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:
527 528
    case AV_PIX_FMT_YUVA422P:
    case AV_PIX_FMT_YUVA444P:
529
        cpyresult = libopenjpeg_copy_unpacked8(avctx, frame, image);
530
        break;
531 532 533 534
    case AV_PIX_FMT_GRAY16:
    case AV_PIX_FMT_YUV420P9:
    case AV_PIX_FMT_YUV422P9:
    case AV_PIX_FMT_YUV444P9:
535 536 537
    case AV_PIX_FMT_YUVA420P9:
    case AV_PIX_FMT_YUVA422P9:
    case AV_PIX_FMT_YUVA444P9:
538 539 540
    case AV_PIX_FMT_YUV444P10:
    case AV_PIX_FMT_YUV422P10:
    case AV_PIX_FMT_YUV420P10:
541 542 543
    case AV_PIX_FMT_YUVA444P10:
    case AV_PIX_FMT_YUVA422P10:
    case AV_PIX_FMT_YUVA420P10:
544 545 546 547 548 549
    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:
550 551 552
    case AV_PIX_FMT_YUV444P16:
    case AV_PIX_FMT_YUV422P16:
    case AV_PIX_FMT_YUV420P16:
553 554 555
    case AV_PIX_FMT_YUVA444P16:
    case AV_PIX_FMT_YUVA422P16:
    case AV_PIX_FMT_YUVA420P16:
556
        cpyresult = libopenjpeg_copy_unpacked16(avctx, frame, image);
557 558
        break;
    default:
559 560 561
        av_log(avctx, AV_LOG_ERROR,
               "The frame's pixel format '%s' is not supported\n",
               av_get_pix_fmt_name(avctx->pix_fmt));
562 563 564 565 566
        return AVERROR(EINVAL);
        break;
    }

    if (!cpyresult) {
567 568
        av_log(avctx, AV_LOG_ERROR,
               "Could not copy the frame data to the internal image buffer\n");
569 570 571
        return -1;
    }

572
    cio_seek(stream, 0);
573 574 575 576 577 578
    if (!opj_encode(compress, stream, image, NULL)) {
        av_log(avctx, AV_LOG_ERROR, "Error during the opj encode\n");
        return -1;
    }

    len = cio_tell(stream);
579 580
    if ((ret = ff_alloc_packet2(avctx, pkt, len)) < 0) {
        return ret;
581 582
    }

583 584 585 586
    memcpy(pkt->data, stream->buffer, len);
    pkt->flags |= AV_PKT_FLAG_KEY;
    *got_packet = 1;
    return 0;
587 588 589 590 591 592
}

static av_cold int libopenjpeg_encode_close(AVCodecContext *avctx)
{
    LibOpenJPEGContext *ctx = avctx->priv_data;

593 594
    opj_cio_close(ctx->stream);
    ctx->stream = NULL;
595
    opj_destroy_compress(ctx->compress);
596
    ctx->compress = NULL;
597
    opj_image_destroy(ctx->image);
598
    ctx->image = NULL;
599
    av_freep(&avctx->coded_frame);
600
    return 0;
601 602
}

603 604 605
#define OFFSET(x) offsetof(LibOpenJPEGContext, x)
#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
static const AVOption options[] = {
606
    { "format",        "Codec Format",      OFFSET(format),        AV_OPT_TYPE_INT,   { .i64 = CODEC_JP2   }, CODEC_J2K, CODEC_JP2,   VE, "format"      },
607 608
    { "j2k",           NULL,                0,                     AV_OPT_TYPE_CONST, { .i64 = CODEC_J2K   }, 0,         0,           VE, "format"      },
    { "jp2",           NULL,                0,                     AV_OPT_TYPE_CONST, { .i64 = CODEC_JP2   }, 0,         0,           VE, "format"      },
609
    { "profile",       NULL,                OFFSET(profile),       AV_OPT_TYPE_INT,   { .i64 = STD_RSIZ    }, STD_RSIZ,  CINEMA4K,    VE, "profile"     },
610 611 612
    { "jpeg2000",      NULL,                0,                     AV_OPT_TYPE_CONST, { .i64 = STD_RSIZ    }, 0,         0,           VE, "profile"     },
    { "cinema2k",      NULL,                0,                     AV_OPT_TYPE_CONST, { .i64 = CINEMA2K    }, 0,         0,           VE, "profile"     },
    { "cinema4k",      NULL,                0,                     AV_OPT_TYPE_CONST, { .i64 = CINEMA4K    }, 0,         0,           VE, "profile"     },
613
    { "cinema_mode",   "Digital Cinema",    OFFSET(cinema_mode),   AV_OPT_TYPE_INT,   { .i64 = OFF         }, OFF,       CINEMA4K_24, VE, "cinema_mode" },
614 615 616 617
    { "off",           NULL,                0,                     AV_OPT_TYPE_CONST, { .i64 = OFF         }, 0,         0,           VE, "cinema_mode" },
    { "2k_24",         NULL,                0,                     AV_OPT_TYPE_CONST, { .i64 = CINEMA2K_24 }, 0,         0,           VE, "cinema_mode" },
    { "2k_48",         NULL,                0,                     AV_OPT_TYPE_CONST, { .i64 = CINEMA2K_48 }, 0,         0,           VE, "cinema_mode" },
    { "4k_24",         NULL,                0,                     AV_OPT_TYPE_CONST, { .i64 = CINEMA4K_24 }, 0,         0,           VE, "cinema_mode" },
618
    { "prog_order",    "Progression Order", OFFSET(prog_order),    AV_OPT_TYPE_INT,   { .i64 = LRCP        }, LRCP,      CPRL,        VE, "prog_order"  },
619 620 621 622 623
    { "lrcp",          NULL,                0,                     AV_OPT_TYPE_CONST, { .i64 = LRCP        }, 0,         0,           VE, "prog_order"  },
    { "rlcp",          NULL,                0,                     AV_OPT_TYPE_CONST, { .i64 = RLCP        }, 0,         0,           VE, "prog_order"  },
    { "rpcl",          NULL,                0,                     AV_OPT_TYPE_CONST, { .i64 = RPCL        }, 0,         0,           VE, "prog_order"  },
    { "pcrl",          NULL,                0,                     AV_OPT_TYPE_CONST, { .i64 = PCRL        }, 0,         0,           VE, "prog_order"  },
    { "cprl",          NULL,                0,                     AV_OPT_TYPE_CONST, { .i64 = CPRL        }, 0,         0,           VE, "prog_order"  },
624 625 626 627 628
    { "numresolution", NULL,                OFFSET(numresolution), AV_OPT_TYPE_INT,   { .i64 = 6           }, 1,         INT_MAX,     VE                },
    { "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                },
629 630 631
    { NULL },
};

632
static const AVClass openjpeg_class = {
633 634 635 636 637
    .class_name = "libopenjpeg",
    .item_name  = av_default_item_name,
    .option     = options,
    .version    = LIBAVUTIL_VERSION_INT,
};
638 639

AVCodec ff_libopenjpeg_encoder = {
640
    .name           = "libopenjpeg",
641
    .long_name      = NULL_IF_CONFIG_SMALL("OpenJPEG JPEG 2000"),
642
    .type           = AVMEDIA_TYPE_VIDEO,
643
    .id             = AV_CODEC_ID_JPEG2000,
644
    .priv_data_size = sizeof(LibOpenJPEGContext),
645
    .init           = libopenjpeg_encode_init,
646
    .encode2        = libopenjpeg_encode_frame,
647 648
    .close          = libopenjpeg_encode_close,
    .capabilities   = 0,
649
    .pix_fmts       = (const enum AVPixelFormat[]) {
650
        AV_PIX_FMT_RGB24, AV_PIX_FMT_RGBA, AV_PIX_FMT_RGB48, AV_PIX_FMT_RGBA64,
651 652
        AV_PIX_FMT_GBR24P,
        AV_PIX_FMT_GBRP9, AV_PIX_FMT_GBRP10, AV_PIX_FMT_GBRP12, AV_PIX_FMT_GBRP14, AV_PIX_FMT_GBRP16,
653
        AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY8A, AV_PIX_FMT_GRAY16,
654
        AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUVA420P,
655 656
        AV_PIX_FMT_YUV440P, AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUVA422P,
        AV_PIX_FMT_YUV411P, AV_PIX_FMT_YUV410P, AV_PIX_FMT_YUVA444P,
657
        AV_PIX_FMT_YUV420P9, AV_PIX_FMT_YUV422P9, AV_PIX_FMT_YUV444P9,
658
        AV_PIX_FMT_YUVA420P9, AV_PIX_FMT_YUVA422P9, AV_PIX_FMT_YUVA444P9,
659
        AV_PIX_FMT_YUV420P10, AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUV444P10,
660
        AV_PIX_FMT_YUVA420P10, AV_PIX_FMT_YUVA422P10, AV_PIX_FMT_YUVA444P10,
661 662
        AV_PIX_FMT_YUV420P12, AV_PIX_FMT_YUV422P12, AV_PIX_FMT_YUV444P12,
        AV_PIX_FMT_YUV420P14, AV_PIX_FMT_YUV422P14, AV_PIX_FMT_YUV444P14,
663
        AV_PIX_FMT_YUV420P16, AV_PIX_FMT_YUV422P16, AV_PIX_FMT_YUV444P16,
664
        AV_PIX_FMT_YUVA420P16, AV_PIX_FMT_YUVA422P16, AV_PIX_FMT_YUVA444P16,
665
        AV_PIX_FMT_XYZ12,
666
        AV_PIX_FMT_NONE
667
    },
668
    .priv_class     = &openjpeg_class,
669
};