1/* 2 * JPEG 2000 encoding support via OpenJPEG 3 * Copyright (c) 2011 Michael Bradshaw <mjbshaw gmail com> 4 * 5 * This file is part of FFmpeg. 6 * 7 * FFmpeg is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU Lesser General Public 9 * License as published by the Free Software Foundation; either 10 * version 2.1 of the License, or (at your option) any later version. 11 * 12 * FFmpeg is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Lesser General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public 18 * License along with FFmpeg; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 */ 21 22/** 23 * @file 24 * JPEG 2000 encoder using libopenjpeg 25 */ 26 27#include "libavutil/common.h" 28#include "libavutil/imgutils.h" 29#include "libavutil/intreadwrite.h" 30#include "libavutil/opt.h" 31#include "avcodec.h" 32#include "codec_internal.h" 33#include "encode.h" 34#include <openjpeg.h> 35 36typedef struct LibOpenJPEGContext { 37 AVClass *avclass; 38 opj_cparameters_t enc_params; 39 int format; 40 int profile; 41 int prog_order; 42 int cinema_mode; 43 int numresolution; 44 int irreversible; 45 int disto_alloc; 46 int fixed_quality; 47} LibOpenJPEGContext; 48 49static void error_callback(const char *msg, void *data) 50{ 51 av_log(data, AV_LOG_ERROR, "%s\n", msg); 52} 53 54static void warning_callback(const char *msg, void *data) 55{ 56 av_log(data, AV_LOG_WARNING, "%s\n", msg); 57} 58 59static void info_callback(const char *msg, void *data) 60{ 61 av_log(data, AV_LOG_DEBUG, "%s\n", msg); 62} 63 64typedef struct PacketWriter { 65 int pos; 66 AVPacket *packet; 67} PacketWriter; 68 69static OPJ_SIZE_T stream_write(void *out_buffer, OPJ_SIZE_T nb_bytes, void *user_data) 70{ 71 PacketWriter *writer = user_data; 72 AVPacket *packet = writer->packet; 73 int remaining = packet->size - writer->pos; 74 if (nb_bytes > remaining) { 75 OPJ_SIZE_T needed = nb_bytes - remaining; 76 int max_growth = INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE - packet->size; 77 if (needed > max_growth) { 78 return (OPJ_SIZE_T)-1; 79 } 80 if (av_grow_packet(packet, (int)needed)) { 81 return (OPJ_SIZE_T)-1; 82 } 83 } 84 memcpy(packet->data + writer->pos, out_buffer, nb_bytes); 85 writer->pos += (int)nb_bytes; 86 return nb_bytes; 87} 88 89static OPJ_OFF_T stream_skip(OPJ_OFF_T nb_bytes, void *user_data) 90{ 91 PacketWriter *writer = user_data; 92 AVPacket *packet = writer->packet; 93 if (nb_bytes < 0) { 94 if (writer->pos == 0) { 95 return (OPJ_SIZE_T)-1; 96 } 97 if (nb_bytes + writer->pos < 0) { 98 nb_bytes = -writer->pos; 99 } 100 } else { 101 int remaining = packet->size - writer->pos; 102 if (nb_bytes > remaining) { 103 OPJ_SIZE_T needed = nb_bytes - remaining; 104 int max_growth = INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE - packet->size; 105 if (needed > max_growth) { 106 return (OPJ_SIZE_T)-1; 107 } 108 if (av_grow_packet(packet, (int)needed)) { 109 return (OPJ_SIZE_T)-1; 110 } 111 } 112 } 113 writer->pos += (int)nb_bytes; 114 return nb_bytes; 115} 116 117static OPJ_BOOL stream_seek(OPJ_OFF_T nb_bytes, void *user_data) 118{ 119 PacketWriter *writer = user_data; 120 AVPacket *packet = writer->packet; 121 if (nb_bytes < 0) { 122 return OPJ_FALSE; 123 } 124 if (nb_bytes > packet->size) { 125 if (nb_bytes > INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE || 126 av_grow_packet(packet, (int)nb_bytes - packet->size)) { 127 return OPJ_FALSE; 128 } 129 } 130 writer->pos = (int)nb_bytes; 131 return OPJ_TRUE; 132} 133 134static void cinema_parameters(opj_cparameters_t *p) 135{ 136 p->tile_size_on = 0; 137 p->cp_tdx = 1; 138 p->cp_tdy = 1; 139 140 /* Tile part */ 141 p->tp_flag = 'C'; 142 p->tp_on = 1; 143 144 /* Tile and Image shall be at (0, 0) */ 145 p->cp_tx0 = 0; 146 p->cp_ty0 = 0; 147 p->image_offset_x0 = 0; 148 p->image_offset_y0 = 0; 149 150 /* Codeblock size= 32 * 32 */ 151 p->cblockw_init = 32; 152 p->cblockh_init = 32; 153 p->csty |= 0x01; 154 155 /* The progression order shall be CPRL */ 156 p->prog_order = OPJ_CPRL; 157 158 /* No ROI */ 159 p->roi_compno = -1; 160 161 /* No subsampling */ 162 p->subsampling_dx = 1; 163 p->subsampling_dy = 1; 164 165 /* 9-7 transform */ 166 p->irreversible = 1; 167 168 p->tcp_mct = 1; 169} 170 171static opj_image_t *mj2_create_image(AVCodecContext *avctx, opj_cparameters_t *parameters) 172{ 173 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt); 174 opj_image_cmptparm_t cmptparm[4] = {{0}}; 175 opj_image_t *img; 176 int i; 177 int sub_dx[4]; 178 int sub_dy[4]; 179 int numcomps; 180 OPJ_COLOR_SPACE color_space = OPJ_CLRSPC_UNKNOWN; 181 182 sub_dx[0] = sub_dx[3] = 1; 183 sub_dy[0] = sub_dy[3] = 1; 184 sub_dx[1] = sub_dx[2] = 1 << desc->log2_chroma_w; 185 sub_dy[1] = sub_dy[2] = 1 << desc->log2_chroma_h; 186 187 numcomps = desc->nb_components; 188 189 switch (avctx->pix_fmt) { 190 case AV_PIX_FMT_GRAY8: 191 case AV_PIX_FMT_YA8: 192 case AV_PIX_FMT_GRAY10: 193 case AV_PIX_FMT_GRAY12: 194 case AV_PIX_FMT_GRAY14: 195 case AV_PIX_FMT_GRAY16: 196 case AV_PIX_FMT_YA16: 197 color_space = OPJ_CLRSPC_GRAY; 198 break; 199 case AV_PIX_FMT_RGB24: 200 case AV_PIX_FMT_RGBA: 201 case AV_PIX_FMT_RGB48: 202 case AV_PIX_FMT_RGBA64: 203 case AV_PIX_FMT_GBR24P: 204 case AV_PIX_FMT_GBRP9: 205 case AV_PIX_FMT_GBRP10: 206 case AV_PIX_FMT_GBRP12: 207 case AV_PIX_FMT_GBRP14: 208 case AV_PIX_FMT_GBRP16: 209 case AV_PIX_FMT_XYZ12: 210 color_space = OPJ_CLRSPC_SRGB; 211 break; 212 case AV_PIX_FMT_YUV410P: 213 case AV_PIX_FMT_YUV411P: 214 case AV_PIX_FMT_YUV420P: 215 case AV_PIX_FMT_YUV422P: 216 case AV_PIX_FMT_YUV440P: 217 case AV_PIX_FMT_YUV444P: 218 case AV_PIX_FMT_YUVA420P: 219 case AV_PIX_FMT_YUVA422P: 220 case AV_PIX_FMT_YUVA444P: 221 case AV_PIX_FMT_YUV420P9: 222 case AV_PIX_FMT_YUV422P9: 223 case AV_PIX_FMT_YUV444P9: 224 case AV_PIX_FMT_YUVA420P9: 225 case AV_PIX_FMT_YUVA422P9: 226 case AV_PIX_FMT_YUVA444P9: 227 case AV_PIX_FMT_YUV420P10: 228 case AV_PIX_FMT_YUV422P10: 229 case AV_PIX_FMT_YUV444P10: 230 case AV_PIX_FMT_YUVA420P10: 231 case AV_PIX_FMT_YUVA422P10: 232 case AV_PIX_FMT_YUVA444P10: 233 case AV_PIX_FMT_YUV420P12: 234 case AV_PIX_FMT_YUV422P12: 235 case AV_PIX_FMT_YUV444P12: 236 case AV_PIX_FMT_YUV420P14: 237 case AV_PIX_FMT_YUV422P14: 238 case AV_PIX_FMT_YUV444P14: 239 case AV_PIX_FMT_YUV420P16: 240 case AV_PIX_FMT_YUV422P16: 241 case AV_PIX_FMT_YUV444P16: 242 case AV_PIX_FMT_YUVA420P16: 243 case AV_PIX_FMT_YUVA422P16: 244 case AV_PIX_FMT_YUVA444P16: 245 color_space = OPJ_CLRSPC_SYCC; 246 break; 247 default: 248 av_log(avctx, AV_LOG_ERROR, 249 "The requested pixel format '%s' is not supported\n", 250 av_get_pix_fmt_name(avctx->pix_fmt)); 251 return NULL; 252 } 253 254 for (i = 0; i < numcomps; i++) { 255 cmptparm[i].prec = desc->comp[i].depth; 256 cmptparm[i].bpp = desc->comp[i].depth; 257 cmptparm[i].sgnd = 0; 258 cmptparm[i].dx = sub_dx[i]; 259 cmptparm[i].dy = sub_dy[i]; 260 cmptparm[i].w = (avctx->width + sub_dx[i] - 1) / sub_dx[i]; 261 cmptparm[i].h = (avctx->height + sub_dy[i] - 1) / sub_dy[i]; 262 } 263 264 img = opj_image_create(numcomps, cmptparm, color_space); 265 266 if (!img) 267 return NULL; 268 269 // x0, y0 is the top left corner of the image 270 // x1, y1 is the width, height of the reference grid 271 img->x0 = 0; 272 img->y0 = 0; 273 img->x1 = (avctx->width - 1) * parameters->subsampling_dx + 1; 274 img->y1 = (avctx->height - 1) * parameters->subsampling_dy + 1; 275 276 return img; 277} 278 279static av_cold int libopenjpeg_encode_init(AVCodecContext *avctx) 280{ 281 LibOpenJPEGContext *ctx = avctx->priv_data; 282 int err = 0; 283 284 opj_set_default_encoder_parameters(&ctx->enc_params); 285 286 switch (ctx->cinema_mode) { 287 case OPJ_CINEMA2K_24: 288 ctx->enc_params.rsiz = OPJ_PROFILE_CINEMA_2K; 289 ctx->enc_params.max_cs_size = OPJ_CINEMA_24_CS; 290 ctx->enc_params.max_comp_size = OPJ_CINEMA_24_COMP; 291 break; 292 case OPJ_CINEMA2K_48: 293 ctx->enc_params.rsiz = OPJ_PROFILE_CINEMA_2K; 294 ctx->enc_params.max_cs_size = OPJ_CINEMA_48_CS; 295 ctx->enc_params.max_comp_size = OPJ_CINEMA_48_COMP; 296 break; 297 case OPJ_CINEMA4K_24: 298 ctx->enc_params.rsiz = OPJ_PROFILE_CINEMA_4K; 299 ctx->enc_params.max_cs_size = OPJ_CINEMA_24_CS; 300 ctx->enc_params.max_comp_size = OPJ_CINEMA_24_COMP; 301 break; 302 } 303 304 switch (ctx->profile) { 305 case OPJ_CINEMA2K: 306 if (ctx->enc_params.rsiz == OPJ_PROFILE_CINEMA_4K) { 307 err = AVERROR(EINVAL); 308 break; 309 } 310 ctx->enc_params.rsiz = OPJ_PROFILE_CINEMA_2K; 311 break; 312 case OPJ_CINEMA4K: 313 if (ctx->enc_params.rsiz == OPJ_PROFILE_CINEMA_2K) { 314 err = AVERROR(EINVAL); 315 break; 316 } 317 ctx->enc_params.rsiz = OPJ_PROFILE_CINEMA_4K; 318 break; 319 } 320 321 if (err) { 322 av_log(avctx, AV_LOG_ERROR, 323 "Invalid parameter pairing: cinema_mode and profile conflict.\n"); 324 return err; 325 } 326 327 if (!ctx->numresolution) { 328 ctx->numresolution = 6; 329 while (FFMIN(avctx->width, avctx->height) >> ctx->numresolution < 1) 330 ctx->numresolution --; 331 } 332 333 ctx->enc_params.prog_order = ctx->prog_order; 334 ctx->enc_params.numresolution = ctx->numresolution; 335 ctx->enc_params.irreversible = ctx->irreversible; 336 ctx->enc_params.cp_disto_alloc = ctx->disto_alloc; 337 ctx->enc_params.cp_fixed_quality = ctx->fixed_quality; 338 ctx->enc_params.tcp_numlayers = 1; 339 ctx->enc_params.tcp_rates[0] = FFMAX(avctx->compression_level, 0) * 2; 340 341 if (ctx->cinema_mode > 0) { 342 cinema_parameters(&ctx->enc_params); 343 } 344 345 return 0; 346} 347 348static int libopenjpeg_copy_packed8(AVCodecContext *avctx, const uint8_t *src[4], 349 const int linesize[4], opj_image_t *image) 350{ 351 int compno; 352 int x; 353 int y; 354 int *image_line; 355 int frame_index; 356 const int numcomps = image->numcomps; 357 358 for (compno = 0; compno < numcomps; ++compno) { 359 if (image->comps[compno].w > linesize[0] / numcomps) { 360 av_log(avctx, AV_LOG_ERROR, "Error: frame's linesize is too small for the image\n"); 361 return 0; 362 } 363 } 364 365 for (compno = 0; compno < numcomps; ++compno) { 366 for (y = 0; y < avctx->height; ++y) { 367 image_line = image->comps[compno].data + y * image->comps[compno].w; 368 frame_index = y * linesize[0] + compno; 369 for (x = 0; x < avctx->width; ++x) { 370 image_line[x] = src[0][frame_index]; 371 frame_index += numcomps; 372 } 373 for (; x < image->comps[compno].w; ++x) { 374 image_line[x] = image_line[x - 1]; 375 } 376 } 377 for (; y < image->comps[compno].h; ++y) { 378 image_line = image->comps[compno].data + y * image->comps[compno].w; 379 for (x = 0; x < image->comps[compno].w; ++x) { 380 image_line[x] = image_line[x - (int)image->comps[compno].w]; 381 } 382 } 383 } 384 385 return 1; 386} 387 388// for XYZ 12 bit 389static int libopenjpeg_copy_packed12(AVCodecContext *avctx, const uint8_t *src[4], 390 const int linesize[4], opj_image_t *image) 391{ 392 int compno; 393 int x, y; 394 int *image_line; 395 int frame_index; 396 const int numcomps = image->numcomps; 397 const uint16_t *frame_ptr = (const uint16_t *)src[0]; 398 399 for (compno = 0; compno < numcomps; ++compno) { 400 if (image->comps[compno].w > linesize[0] / numcomps) { 401 av_log(avctx, AV_LOG_ERROR, "Error: frame's linesize is too small for the image\n"); 402 return 0; 403 } 404 } 405 406 for (compno = 0; compno < numcomps; ++compno) { 407 for (y = 0; y < avctx->height; ++y) { 408 image_line = image->comps[compno].data + y * image->comps[compno].w; 409 frame_index = y * (linesize[0] / 2) + compno; 410 for (x = 0; x < avctx->width; ++x) { 411 image_line[x] = frame_ptr[frame_index] >> 4; 412 frame_index += numcomps; 413 } 414 for (; x < image->comps[compno].w; ++x) { 415 image_line[x] = image_line[x - 1]; 416 } 417 } 418 for (; y < image->comps[compno].h; ++y) { 419 image_line = image->comps[compno].data + y * image->comps[compno].w; 420 for (x = 0; x < image->comps[compno].w; ++x) { 421 image_line[x] = image_line[x - (int)image->comps[compno].w]; 422 } 423 } 424 } 425 426 return 1; 427} 428 429static int libopenjpeg_copy_packed16(AVCodecContext *avctx, const uint8_t *src[4], 430 const int linesize[4], opj_image_t *image) 431{ 432 int compno; 433 int x; 434 int y; 435 int *image_line; 436 int frame_index; 437 const int numcomps = image->numcomps; 438 const uint16_t *frame_ptr = (const uint16_t*)src[0]; 439 440 for (compno = 0; compno < numcomps; ++compno) { 441 if (image->comps[compno].w > linesize[0] / numcomps) { 442 av_log(avctx, AV_LOG_ERROR, "Error: frame's linesize is too small for the image\n"); 443 return 0; 444 } 445 } 446 447 for (compno = 0; compno < numcomps; ++compno) { 448 for (y = 0; y < avctx->height; ++y) { 449 image_line = image->comps[compno].data + y * image->comps[compno].w; 450 frame_index = y * (linesize[0] / 2) + compno; 451 for (x = 0; x < avctx->width; ++x) { 452 image_line[x] = frame_ptr[frame_index]; 453 frame_index += numcomps; 454 } 455 for (; x < image->comps[compno].w; ++x) { 456 image_line[x] = image_line[x - 1]; 457 } 458 } 459 for (; y < image->comps[compno].h; ++y) { 460 image_line = image->comps[compno].data + y * image->comps[compno].w; 461 for (x = 0; x < image->comps[compno].w; ++x) { 462 image_line[x] = image_line[x - (int)image->comps[compno].w]; 463 } 464 } 465 } 466 467 return 1; 468} 469 470static int libopenjpeg_copy_unpacked8(AVCodecContext *avctx, const uint8_t *src[4], 471 const int linesize[4], opj_image_t *image) 472{ 473 int compno; 474 int x; 475 int y; 476 int width; 477 int height; 478 int *image_line; 479 int frame_index; 480 const int numcomps = image->numcomps; 481 482 for (compno = 0; compno < numcomps; ++compno) { 483 if (image->comps[compno].w > linesize[compno]) { 484 av_log(avctx, AV_LOG_ERROR, "Error: frame's linesize is too small for the image\n"); 485 return 0; 486 } 487 } 488 489 for (compno = 0; compno < numcomps; ++compno) { 490 width = (avctx->width + image->comps[compno].dx - 1) / image->comps[compno].dx; 491 height = (avctx->height + image->comps[compno].dy - 1) / image->comps[compno].dy; 492 for (y = 0; y < height; ++y) { 493 image_line = image->comps[compno].data + y * image->comps[compno].w; 494 frame_index = y * linesize[compno]; 495 for (x = 0; x < width; ++x) 496 image_line[x] = src[compno][frame_index++]; 497 for (; x < image->comps[compno].w; ++x) { 498 image_line[x] = image_line[x - 1]; 499 } 500 } 501 for (; y < image->comps[compno].h; ++y) { 502 image_line = image->comps[compno].data + y * image->comps[compno].w; 503 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 return 1; 510} 511 512static int libopenjpeg_copy_unpacked16(AVCodecContext *avctx, const uint8_t *src[4], 513 const int linesize[4], opj_image_t *image) 514{ 515 int compno; 516 int x; 517 int y; 518 int width; 519 int height; 520 int *image_line; 521 int frame_index; 522 const int numcomps = image->numcomps; 523 524 for (compno = 0; compno < numcomps; ++compno) { 525 if (image->comps[compno].w > linesize[compno]) { 526 av_log(avctx, AV_LOG_ERROR, "Error: frame's linesize is too small for the image\n"); 527 return 0; 528 } 529 } 530 531 for (compno = 0; compno < numcomps; ++compno) { 532 const uint16_t *frame_ptr = (const uint16_t *)src[compno]; 533 width = (avctx->width + image->comps[compno].dx - 1) / image->comps[compno].dx; 534 height = (avctx->height + image->comps[compno].dy - 1) / image->comps[compno].dy; 535 for (y = 0; y < height; ++y) { 536 image_line = image->comps[compno].data + y * image->comps[compno].w; 537 frame_index = y * (linesize[compno] / 2); 538 for (x = 0; x < width; ++x) 539 image_line[x] = frame_ptr[frame_index++]; 540 for (; x < image->comps[compno].w; ++x) { 541 image_line[x] = image_line[x - 1]; 542 } 543 } 544 for (; y < image->comps[compno].h; ++y) { 545 image_line = image->comps[compno].data + y * image->comps[compno].w; 546 for (x = 0; x < image->comps[compno].w; ++x) { 547 image_line[x] = image_line[x - (int)image->comps[compno].w]; 548 } 549 } 550 } 551 552 return 1; 553} 554 555static int libopenjpeg_encode_frame(AVCodecContext *avctx, AVPacket *pkt, 556 const AVFrame *frame, int *got_packet) 557{ 558 LibOpenJPEGContext *ctx = avctx->priv_data; 559 int ret; 560 int cpyresult = 0; 561 PacketWriter writer = { 0 }; 562 opj_codec_t *compress = NULL; 563 opj_stream_t *stream = NULL; 564 opj_image_t *image = mj2_create_image(avctx, &ctx->enc_params); 565 const uint8_t *data[4] = { frame->data[0], frame->data[1], 566 frame->data[2], frame->data[3] }; 567 int linesize[4] = { frame->linesize[0], frame->linesize[1], 568 frame->linesize[2], frame->linesize[3] }; 569 if (!image) { 570 av_log(avctx, AV_LOG_ERROR, "Error creating the mj2 image\n"); 571 ret = AVERROR(EINVAL); 572 goto done; 573 } 574 575 switch (avctx->pix_fmt) { 576 case AV_PIX_FMT_RGB24: 577 case AV_PIX_FMT_RGBA: 578 case AV_PIX_FMT_YA8: 579 cpyresult = libopenjpeg_copy_packed8(avctx, data, linesize, image); 580 break; 581 case AV_PIX_FMT_XYZ12: 582 cpyresult = libopenjpeg_copy_packed12(avctx, data, linesize, image); 583 break; 584 case AV_PIX_FMT_RGB48: 585 case AV_PIX_FMT_RGBA64: 586 case AV_PIX_FMT_YA16: 587 cpyresult = libopenjpeg_copy_packed16(avctx, data, linesize, image); 588 break; 589 case AV_PIX_FMT_GBR24P: 590 case AV_PIX_FMT_GBRP9: 591 case AV_PIX_FMT_GBRP10: 592 case AV_PIX_FMT_GBRP12: 593 case AV_PIX_FMT_GBRP14: 594 case AV_PIX_FMT_GBRP16: 595 data[0] = frame->data[2]; // swap to be rgb 596 data[1] = frame->data[0]; 597 data[2] = frame->data[1]; 598 linesize[0] = frame->linesize[2]; 599 linesize[1] = frame->linesize[0]; 600 linesize[2] = frame->linesize[1]; 601 if (avctx->pix_fmt == AV_PIX_FMT_GBR24P) { 602 cpyresult = libopenjpeg_copy_unpacked8(avctx, data, linesize, image); 603 } else { 604 cpyresult = libopenjpeg_copy_unpacked16(avctx, data, linesize, image); 605 } 606 break; 607 case AV_PIX_FMT_GRAY8: 608 case AV_PIX_FMT_YUV410P: 609 case AV_PIX_FMT_YUV411P: 610 case AV_PIX_FMT_YUV420P: 611 case AV_PIX_FMT_YUV422P: 612 case AV_PIX_FMT_YUV440P: 613 case AV_PIX_FMT_YUV444P: 614 case AV_PIX_FMT_YUVA420P: 615 case AV_PIX_FMT_YUVA422P: 616 case AV_PIX_FMT_YUVA444P: 617 cpyresult = libopenjpeg_copy_unpacked8(avctx, data, linesize, image); 618 break; 619 case AV_PIX_FMT_GRAY10: 620 case AV_PIX_FMT_GRAY12: 621 case AV_PIX_FMT_GRAY14: 622 case AV_PIX_FMT_GRAY16: 623 case AV_PIX_FMT_YUV420P9: 624 case AV_PIX_FMT_YUV422P9: 625 case AV_PIX_FMT_YUV444P9: 626 case AV_PIX_FMT_YUVA420P9: 627 case AV_PIX_FMT_YUVA422P9: 628 case AV_PIX_FMT_YUVA444P9: 629 case AV_PIX_FMT_YUV444P10: 630 case AV_PIX_FMT_YUV422P10: 631 case AV_PIX_FMT_YUV420P10: 632 case AV_PIX_FMT_YUVA444P10: 633 case AV_PIX_FMT_YUVA422P10: 634 case AV_PIX_FMT_YUVA420P10: 635 case AV_PIX_FMT_YUV420P12: 636 case AV_PIX_FMT_YUV422P12: 637 case AV_PIX_FMT_YUV444P12: 638 case AV_PIX_FMT_YUV420P14: 639 case AV_PIX_FMT_YUV422P14: 640 case AV_PIX_FMT_YUV444P14: 641 case AV_PIX_FMT_YUV444P16: 642 case AV_PIX_FMT_YUV422P16: 643 case AV_PIX_FMT_YUV420P16: 644 case AV_PIX_FMT_YUVA444P16: 645 case AV_PIX_FMT_YUVA422P16: 646 case AV_PIX_FMT_YUVA420P16: 647 cpyresult = libopenjpeg_copy_unpacked16(avctx, data, linesize, image); 648 break; 649 default: 650 av_log(avctx, AV_LOG_ERROR, 651 "The frame's pixel format '%s' is not supported\n", 652 av_get_pix_fmt_name(avctx->pix_fmt)); 653 ret = AVERROR(EINVAL); 654 goto done; 655 break; 656 } 657 658 if (!cpyresult) { 659 av_log(avctx, AV_LOG_ERROR, 660 "Could not copy the frame data to the internal image buffer\n"); 661 ret = -1; 662 goto done; 663 } 664 665 if ((ret = ff_alloc_packet(avctx, pkt, 1024)) < 0) 666 goto done; 667 668 compress = opj_create_compress(ctx->format); 669 if (!compress) { 670 av_log(avctx, AV_LOG_ERROR, "Error creating the compressor\n"); 671 ret = AVERROR(ENOMEM); 672 goto done; 673 } 674 675 if (!opj_set_error_handler(compress, error_callback, avctx) || 676 !opj_set_warning_handler(compress, warning_callback, avctx) || 677 !opj_set_info_handler(compress, info_callback, avctx)) { 678 av_log(avctx, AV_LOG_ERROR, "Error setting the compressor handlers\n"); 679 ret = AVERROR_EXTERNAL; 680 goto done; 681 } 682 683 if (!opj_setup_encoder(compress, &ctx->enc_params, image)) { 684 av_log(avctx, AV_LOG_ERROR, "Error setting up the compressor\n"); 685 ret = AVERROR_EXTERNAL; 686 goto done; 687 } 688 stream = opj_stream_default_create(OPJ_STREAM_WRITE); 689 690 if (!stream) { 691 av_log(avctx, AV_LOG_ERROR, "Error creating the cio stream\n"); 692 ret = AVERROR(ENOMEM); 693 goto done; 694 } 695 696 writer.packet = pkt; 697 opj_stream_set_write_function(stream, stream_write); 698 opj_stream_set_skip_function(stream, stream_skip); 699 opj_stream_set_seek_function(stream, stream_seek); 700 opj_stream_set_user_data(stream, &writer, NULL); 701 702 if (!opj_start_compress(compress, image, stream) || 703 !opj_encode(compress, stream) || 704 !opj_end_compress(compress, stream)) { 705 av_log(avctx, AV_LOG_ERROR, "Error during the opj encode\n"); 706 ret = AVERROR_EXTERNAL; 707 goto done; 708 } 709 710 av_shrink_packet(pkt, writer.pos); 711 712 *got_packet = 1; 713 ret = 0; 714 715done: 716 opj_stream_destroy(stream); 717 opj_destroy_codec(compress); 718 opj_image_destroy(image); 719 return ret; 720} 721 722#define OFFSET(x) offsetof(LibOpenJPEGContext, x) 723#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM 724static const AVOption options[] = { 725 { "format", "Codec Format", OFFSET(format), AV_OPT_TYPE_INT, { .i64 = OPJ_CODEC_JP2 }, OPJ_CODEC_J2K, OPJ_CODEC_JP2, VE, "format" }, 726 { "j2k", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = OPJ_CODEC_J2K }, 0, 0, VE, "format" }, 727 { "jp2", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = OPJ_CODEC_JP2 }, 0, 0, VE, "format" }, 728 { "profile", NULL, OFFSET(profile), AV_OPT_TYPE_INT, { .i64 = OPJ_STD_RSIZ }, OPJ_STD_RSIZ, OPJ_CINEMA4K, VE, "profile" }, 729 { "jpeg2000", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = OPJ_STD_RSIZ }, 0, 0, VE, "profile" }, 730 { "cinema2k", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = OPJ_CINEMA2K }, 0, 0, VE, "profile" }, 731 { "cinema4k", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = OPJ_CINEMA4K }, 0, 0, VE, "profile" }, 732 { "cinema_mode", "Digital Cinema", OFFSET(cinema_mode), AV_OPT_TYPE_INT, { .i64 = OPJ_OFF }, OPJ_OFF, OPJ_CINEMA4K_24, VE, "cinema_mode" }, 733 { "off", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = OPJ_OFF }, 0, 0, VE, "cinema_mode" }, 734 { "2k_24", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = OPJ_CINEMA2K_24 }, 0, 0, VE, "cinema_mode" }, 735 { "2k_48", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = OPJ_CINEMA2K_48 }, 0, 0, VE, "cinema_mode" }, 736 { "4k_24", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = OPJ_CINEMA4K_24 }, 0, 0, VE, "cinema_mode" }, 737 { "prog_order", "Progression Order", OFFSET(prog_order), AV_OPT_TYPE_INT, { .i64 = OPJ_LRCP }, OPJ_LRCP, OPJ_CPRL, VE, "prog_order" }, 738 { "lrcp", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = OPJ_LRCP }, 0, 0, VE, "prog_order" }, 739 { "rlcp", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = OPJ_RLCP }, 0, 0, VE, "prog_order" }, 740 { "rpcl", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = OPJ_RPCL }, 0, 0, VE, "prog_order" }, 741 { "pcrl", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = OPJ_PCRL }, 0, 0, VE, "prog_order" }, 742 { "cprl", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = OPJ_CPRL }, 0, 0, VE, "prog_order" }, 743 { "numresolution", NULL, OFFSET(numresolution), AV_OPT_TYPE_INT, { .i64 = 6 }, 0, 33, VE }, 744 { "irreversible", NULL, OFFSET(irreversible), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE }, 745 { "disto_alloc", NULL, OFFSET(disto_alloc), AV_OPT_TYPE_INT, { .i64 = 1 }, 0, 1, VE }, 746 { "fixed_quality", NULL, OFFSET(fixed_quality), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE }, 747 { NULL }, 748}; 749 750static const AVClass openjpeg_class = { 751 .class_name = "libopenjpeg", 752 .item_name = av_default_item_name, 753 .option = options, 754 .version = LIBAVUTIL_VERSION_INT, 755}; 756 757const FFCodec ff_libopenjpeg_encoder = { 758 .p.name = "libopenjpeg", 759 .p.long_name = NULL_IF_CONFIG_SMALL("OpenJPEG JPEG 2000"), 760 .p.type = AVMEDIA_TYPE_VIDEO, 761 .p.id = AV_CODEC_ID_JPEG2000, 762 .priv_data_size = sizeof(LibOpenJPEGContext), 763 .init = libopenjpeg_encode_init, 764 FF_CODEC_ENCODE_CB(libopenjpeg_encode_frame), 765 .p.capabilities = AV_CODEC_CAP_FRAME_THREADS, 766 .p.pix_fmts = (const enum AVPixelFormat[]) { 767 AV_PIX_FMT_RGB24, AV_PIX_FMT_RGBA, AV_PIX_FMT_RGB48, 768 AV_PIX_FMT_RGBA64, AV_PIX_FMT_GBR24P, 769 AV_PIX_FMT_GBRP9, AV_PIX_FMT_GBRP10, AV_PIX_FMT_GBRP12, AV_PIX_FMT_GBRP14, AV_PIX_FMT_GBRP16, 770 AV_PIX_FMT_GRAY8, AV_PIX_FMT_YA8, AV_PIX_FMT_GRAY16, AV_PIX_FMT_YA16, 771 AV_PIX_FMT_GRAY10, AV_PIX_FMT_GRAY12, AV_PIX_FMT_GRAY14, 772 AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUVA420P, 773 AV_PIX_FMT_YUV440P, AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUVA422P, 774 AV_PIX_FMT_YUV411P, AV_PIX_FMT_YUV410P, AV_PIX_FMT_YUVA444P, 775 AV_PIX_FMT_YUV420P9, AV_PIX_FMT_YUV422P9, AV_PIX_FMT_YUV444P9, 776 AV_PIX_FMT_YUVA420P9, AV_PIX_FMT_YUVA422P9, AV_PIX_FMT_YUVA444P9, 777 AV_PIX_FMT_YUV420P10, AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUV444P10, 778 AV_PIX_FMT_YUVA420P10, AV_PIX_FMT_YUVA422P10, AV_PIX_FMT_YUVA444P10, 779 AV_PIX_FMT_YUV420P12, AV_PIX_FMT_YUV422P12, AV_PIX_FMT_YUV444P12, 780 AV_PIX_FMT_YUV420P14, AV_PIX_FMT_YUV422P14, AV_PIX_FMT_YUV444P14, 781 AV_PIX_FMT_YUV420P16, AV_PIX_FMT_YUV422P16, AV_PIX_FMT_YUV444P16, 782 AV_PIX_FMT_YUVA420P16, AV_PIX_FMT_YUVA422P16, AV_PIX_FMT_YUVA444P16, 783 AV_PIX_FMT_XYZ12, 784 AV_PIX_FMT_NONE 785 }, 786 .p.priv_class = &openjpeg_class, 787 .p.wrapper_name = "libopenjpeg", 788}; 789