00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00027 #define OPJ_STATIC
00028 #include <openjpeg.h>
00029
00030 #include "libavutil/avassert.h"
00031 #include "libavutil/common.h"
00032 #include "libavutil/imgutils.h"
00033 #include "libavutil/intreadwrite.h"
00034 #include "libavutil/opt.h"
00035 #include "avcodec.h"
00036 #include "internal.h"
00037
00038 typedef struct {
00039 AVClass *avclass;
00040 opj_image_t *image;
00041 opj_cparameters_t enc_params;
00042 opj_cinfo_t *compress;
00043 opj_event_mgr_t event_mgr;
00044 int format;
00045 int profile;
00046 int prog_order;
00047 int cinema_mode;
00048 int numresolution;
00049 int numlayers;
00050 int disto_alloc;
00051 int fixed_alloc;
00052 int fixed_quality;
00053 } LibOpenJPEGContext;
00054
00055 static void error_callback(const char *msg, void *data)
00056 {
00057 av_log(data, AV_LOG_ERROR, "%s\n", msg);
00058 }
00059
00060 static void warning_callback(const char *msg, void *data)
00061 {
00062 av_log(data, AV_LOG_WARNING, "%s\n", msg);
00063 }
00064
00065 static void info_callback(const char *msg, void *data)
00066 {
00067 av_log(data, AV_LOG_DEBUG, "%s\n", msg);
00068 }
00069
00070 static opj_image_t *mj2_create_image(AVCodecContext *avctx, opj_cparameters_t *parameters)
00071 {
00072 opj_image_cmptparm_t *cmptparm;
00073 opj_image_t *img;
00074 int i;
00075 int sub_dx[4];
00076 int sub_dy[4];
00077 int numcomps;
00078 OPJ_COLOR_SPACE color_space = CLRSPC_UNKNOWN;
00079
00080 sub_dx[0] = sub_dx[3] = 1;
00081 sub_dy[0] = sub_dy[3] = 1;
00082 sub_dx[1] = sub_dx[2] = 1<<av_pix_fmt_descriptors[avctx->pix_fmt].log2_chroma_w;
00083 sub_dy[1] = sub_dy[2] = 1<<av_pix_fmt_descriptors[avctx->pix_fmt].log2_chroma_h;
00084
00085 numcomps = av_pix_fmt_descriptors[avctx->pix_fmt].nb_components;
00086
00087 switch (avctx->pix_fmt) {
00088 case PIX_FMT_GRAY8:
00089 case PIX_FMT_GRAY8A:
00090 case PIX_FMT_GRAY16:
00091 color_space = CLRSPC_GRAY;
00092 break;
00093 case PIX_FMT_RGB24:
00094 case PIX_FMT_RGBA:
00095 case PIX_FMT_RGB48:
00096 case PIX_FMT_RGBA64:
00097 color_space = CLRSPC_SRGB;
00098 break;
00099 case PIX_FMT_YUV410P:
00100 case PIX_FMT_YUV411P:
00101 case PIX_FMT_YUV420P:
00102 case PIX_FMT_YUV422P:
00103 case PIX_FMT_YUV440P:
00104 case PIX_FMT_YUV444P:
00105 case PIX_FMT_YUVA420P:
00106 case PIX_FMT_YUVA422P:
00107 case PIX_FMT_YUVA444P:
00108 case PIX_FMT_YUV420P9:
00109 case PIX_FMT_YUV422P9:
00110 case PIX_FMT_YUV444P9:
00111 case PIX_FMT_YUV420P10:
00112 case PIX_FMT_YUV422P10:
00113 case PIX_FMT_YUV444P10:
00114 case PIX_FMT_YUV420P12:
00115 case PIX_FMT_YUV422P12:
00116 case PIX_FMT_YUV444P12:
00117 case PIX_FMT_YUV420P14:
00118 case PIX_FMT_YUV422P14:
00119 case PIX_FMT_YUV444P14:
00120 case PIX_FMT_YUV420P16:
00121 case PIX_FMT_YUV422P16:
00122 case PIX_FMT_YUV444P16:
00123 color_space = CLRSPC_SYCC;
00124 break;
00125 default:
00126 av_log(avctx, AV_LOG_ERROR,
00127 "The requested pixel format '%s' is not supported\n",
00128 av_get_pix_fmt_name(avctx->pix_fmt));
00129 return NULL;
00130 }
00131
00132 cmptparm = av_mallocz(numcomps * sizeof(*cmptparm));
00133 if (!cmptparm) {
00134 av_log(avctx, AV_LOG_ERROR, "Not enough memory\n");
00135 return NULL;
00136 }
00137 for (i = 0; i < numcomps; i++) {
00138 cmptparm[i].prec = av_pix_fmt_descriptors[avctx->pix_fmt].comp[i].depth_minus1 + 1;
00139 cmptparm[i].bpp = av_pix_fmt_descriptors[avctx->pix_fmt].comp[i].depth_minus1 + 1;
00140 cmptparm[i].sgnd = 0;
00141 cmptparm[i].dx = sub_dx[i];
00142 cmptparm[i].dy = sub_dy[i];
00143 cmptparm[i].w = avctx->width / sub_dx[i];
00144 cmptparm[i].h = avctx->height / sub_dy[i];
00145 }
00146
00147 img = opj_image_create(numcomps, cmptparm, color_space);
00148 av_freep(&cmptparm);
00149 return img;
00150 }
00151
00152 static av_cold int libopenjpeg_encode_init(AVCodecContext *avctx)
00153 {
00154 LibOpenJPEGContext *ctx = avctx->priv_data;
00155 int err = AVERROR(ENOMEM);
00156
00157 opj_set_default_encoder_parameters(&ctx->enc_params);
00158
00159 ctx->enc_params.cp_rsiz = ctx->profile;
00160 ctx->enc_params.mode = !!avctx->global_quality;
00161 ctx->enc_params.cp_cinema = ctx->cinema_mode;
00162 ctx->enc_params.prog_order = ctx->prog_order;
00163 ctx->enc_params.numresolution = ctx->numresolution;
00164 ctx->enc_params.cp_disto_alloc = ctx->disto_alloc;
00165 ctx->enc_params.cp_fixed_alloc = ctx->fixed_alloc;
00166 ctx->enc_params.cp_fixed_quality = ctx->fixed_quality;
00167 ctx->enc_params.tcp_numlayers = ctx->numlayers;
00168 ctx->enc_params.tcp_rates[0] = FFMAX(avctx->compression_level, 0) * 2;
00169
00170 ctx->compress = opj_create_compress(ctx->format);
00171 if (!ctx->compress) {
00172 av_log(avctx, AV_LOG_ERROR, "Error creating the compressor\n");
00173 return AVERROR(ENOMEM);
00174 }
00175
00176 avctx->coded_frame = avcodec_alloc_frame();
00177 if (!avctx->coded_frame) {
00178 av_log(avctx, AV_LOG_ERROR, "Error allocating coded frame\n");
00179 goto fail;
00180 }
00181
00182 ctx->image = mj2_create_image(avctx, &ctx->enc_params);
00183 if (!ctx->image) {
00184 av_log(avctx, AV_LOG_ERROR, "Error creating the mj2 image\n");
00185 err = AVERROR(EINVAL);
00186 goto fail;
00187 }
00188
00189 memset(&ctx->event_mgr, 0, sizeof(opj_event_mgr_t));
00190 ctx->event_mgr.info_handler = info_callback;
00191 ctx->event_mgr.error_handler = error_callback;
00192 ctx->event_mgr.warning_handler = warning_callback;
00193 opj_set_event_mgr((opj_common_ptr)ctx->compress, &ctx->event_mgr, avctx);
00194
00195 return 0;
00196
00197 fail:
00198 av_freep(&ctx->compress);
00199 av_freep(&avctx->coded_frame);
00200 return err;
00201 }
00202
00203 static int libopenjpeg_copy_packed8(AVCodecContext *avctx, const AVFrame *frame, opj_image_t *image)
00204 {
00205 int compno;
00206 int x;
00207 int y;
00208 int image_index;
00209 int frame_index;
00210 const int numcomps = image->numcomps;
00211
00212 for (compno = 0; compno < numcomps; ++compno) {
00213 if (image->comps[compno].w > frame->linesize[0] / numcomps) {
00214 av_log(avctx, AV_LOG_ERROR, "Error: frame's linesize is too small for the image\n");
00215 return 0;
00216 }
00217 }
00218
00219 for (compno = 0; compno < numcomps; ++compno) {
00220 for (y = 0; y < avctx->height; ++y) {
00221 image_index = y * avctx->width;
00222 frame_index = y * frame->linesize[0] + compno;
00223 for (x = 0; x < avctx->width; ++x) {
00224 image->comps[compno].data[image_index++] = frame->data[0][frame_index];
00225 frame_index += numcomps;
00226 }
00227 }
00228 }
00229
00230 return 1;
00231 }
00232
00233 static int libopenjpeg_copy_packed16(AVCodecContext *avctx, const AVFrame *frame, opj_image_t *image)
00234 {
00235 int compno;
00236 int x;
00237 int y;
00238 int image_index;
00239 int frame_index;
00240 const int numcomps = image->numcomps;
00241 uint16_t *frame_ptr = (uint16_t*)frame->data[0];
00242
00243 for (compno = 0; compno < numcomps; ++compno) {
00244 if (image->comps[compno].w > frame->linesize[0] / numcomps) {
00245 av_log(avctx, AV_LOG_ERROR, "Error: frame's linesize is too small for the image\n");
00246 return 0;
00247 }
00248 }
00249
00250 for (compno = 0; compno < numcomps; ++compno) {
00251 for (y = 0; y < avctx->height; ++y) {
00252 image_index = y * avctx->width;
00253 frame_index = y * (frame->linesize[0] / 2) + compno;
00254 for (x = 0; x < avctx->width; ++x) {
00255 image->comps[compno].data[image_index++] = frame_ptr[frame_index];
00256 frame_index += numcomps;
00257 }
00258 }
00259 }
00260
00261 return 1;
00262 }
00263
00264 static int libopenjpeg_copy_unpacked8(AVCodecContext *avctx, const AVFrame *frame, opj_image_t *image)
00265 {
00266 int compno;
00267 int x;
00268 int y;
00269 int width;
00270 int height;
00271 int image_index;
00272 int frame_index;
00273 const int numcomps = image->numcomps;
00274
00275 for (compno = 0; compno < numcomps; ++compno) {
00276 if (image->comps[compno].w > frame->linesize[compno]) {
00277 av_log(avctx, AV_LOG_ERROR, "Error: frame's linesize is too small for the image\n");
00278 return 0;
00279 }
00280 }
00281
00282 for (compno = 0; compno < numcomps; ++compno) {
00283 width = avctx->width / image->comps[compno].dx;
00284 height = avctx->height / image->comps[compno].dy;
00285 for (y = 0; y < height; ++y) {
00286 image_index = y * width;
00287 frame_index = y * frame->linesize[compno];
00288 for (x = 0; x < width; ++x)
00289 image->comps[compno].data[image_index++] = frame->data[compno][frame_index++];
00290 }
00291 }
00292
00293 return 1;
00294 }
00295
00296 static int libopenjpeg_copy_unpacked16(AVCodecContext *avctx, const AVFrame *frame, opj_image_t *image)
00297 {
00298 int compno;
00299 int x;
00300 int y;
00301 int width;
00302 int height;
00303 int image_index;
00304 int frame_index;
00305 const int numcomps = image->numcomps;
00306 uint16_t *frame_ptr;
00307
00308 for (compno = 0; compno < numcomps; ++compno) {
00309 if (image->comps[compno].w > frame->linesize[compno]) {
00310 av_log(avctx, AV_LOG_ERROR, "Error: frame's linesize is too small for the image\n");
00311 return 0;
00312 }
00313 }
00314
00315 for (compno = 0; compno < numcomps; ++compno) {
00316 width = avctx->width / image->comps[compno].dx;
00317 height = avctx->height / image->comps[compno].dy;
00318 frame_ptr = (uint16_t*)frame->data[compno];
00319 for (y = 0; y < height; ++y) {
00320 image_index = y * width;
00321 frame_index = y * (frame->linesize[compno] / 2);
00322 for (x = 0; x < width; ++x)
00323 image->comps[compno].data[image_index++] = frame_ptr[frame_index++];
00324 }
00325 }
00326
00327 return 1;
00328 }
00329
00330 static int libopenjpeg_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
00331 const AVFrame *frame, int *got_packet)
00332 {
00333 LibOpenJPEGContext *ctx = avctx->priv_data;
00334 opj_cinfo_t *compress = ctx->compress;
00335 opj_image_t *image = ctx->image;
00336 opj_cio_t *stream;
00337 int cpyresult = 0;
00338 int ret, len;
00339
00340
00341
00342 image->x0 = 0;
00343 image->y0 = 0;
00344 image->x1 = (avctx->width - 1) * ctx->enc_params.subsampling_dx + 1;
00345 image->y1 = (avctx->height - 1) * ctx->enc_params.subsampling_dy + 1;
00346
00347 switch (avctx->pix_fmt) {
00348 case PIX_FMT_RGB24:
00349 case PIX_FMT_RGBA:
00350 case PIX_FMT_GRAY8A:
00351 cpyresult = libopenjpeg_copy_packed8(avctx, frame, image);
00352 break;
00353 case PIX_FMT_RGB48:
00354 case PIX_FMT_RGBA64:
00355 cpyresult = libopenjpeg_copy_packed16(avctx, frame, image);
00356 break;
00357 case PIX_FMT_GRAY8:
00358 case PIX_FMT_YUV410P:
00359 case PIX_FMT_YUV411P:
00360 case PIX_FMT_YUV420P:
00361 case PIX_FMT_YUV422P:
00362 case PIX_FMT_YUV440P:
00363 case PIX_FMT_YUV444P:
00364 case PIX_FMT_YUVA420P:
00365 case PIX_FMT_YUVA422P:
00366 case PIX_FMT_YUVA444P:
00367 cpyresult = libopenjpeg_copy_unpacked8(avctx, frame, image);
00368 break;
00369 case PIX_FMT_GRAY16:
00370 case PIX_FMT_YUV420P9:
00371 case PIX_FMT_YUV422P9:
00372 case PIX_FMT_YUV444P9:
00373 case PIX_FMT_YUV444P10:
00374 case PIX_FMT_YUV422P10:
00375 case PIX_FMT_YUV420P10:
00376 case PIX_FMT_YUV420P12:
00377 case PIX_FMT_YUV422P12:
00378 case PIX_FMT_YUV444P12:
00379 case PIX_FMT_YUV420P14:
00380 case PIX_FMT_YUV422P14:
00381 case PIX_FMT_YUV444P14:
00382 case PIX_FMT_YUV444P16:
00383 case PIX_FMT_YUV422P16:
00384 case PIX_FMT_YUV420P16:
00385 cpyresult = libopenjpeg_copy_unpacked16(avctx, frame, image);
00386 break;
00387 default:
00388 av_log(avctx, AV_LOG_ERROR,
00389 "The frame's pixel format '%s' is not supported\n",
00390 av_get_pix_fmt_name(avctx->pix_fmt));
00391 return AVERROR(EINVAL);
00392 break;
00393 }
00394
00395 if (!cpyresult) {
00396 av_log(avctx, AV_LOG_ERROR,
00397 "Could not copy the frame data to the internal image buffer\n");
00398 return -1;
00399 }
00400
00401 opj_setup_encoder(compress, &ctx->enc_params, image);
00402 stream = opj_cio_open((opj_common_ptr)compress, NULL, 0);
00403 if (!stream) {
00404 av_log(avctx, AV_LOG_ERROR, "Error creating the cio stream\n");
00405 return AVERROR(ENOMEM);
00406 }
00407
00408 if (!opj_encode(compress, stream, image, NULL)) {
00409 opj_cio_close(stream);
00410 av_log(avctx, AV_LOG_ERROR, "Error during the opj encode\n");
00411 return -1;
00412 }
00413
00414 len = cio_tell(stream);
00415 if ((ret = ff_alloc_packet2(avctx, pkt, len)) < 0) {
00416 opj_cio_close(stream);
00417 return ret;
00418 }
00419
00420 memcpy(pkt->data, stream->buffer, len);
00421 pkt->flags |= AV_PKT_FLAG_KEY;
00422 *got_packet = 1;
00423 opj_cio_close(stream);
00424 return 0;
00425 }
00426
00427 static av_cold int libopenjpeg_encode_close(AVCodecContext *avctx)
00428 {
00429 LibOpenJPEGContext *ctx = avctx->priv_data;
00430
00431 opj_destroy_compress(ctx->compress);
00432 opj_image_destroy(ctx->image);
00433 av_freep(&avctx->coded_frame);
00434 return 0;
00435 }
00436
00437 #define OFFSET(x) offsetof(LibOpenJPEGContext, x)
00438 #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
00439 static const AVOption options[] = {
00440 { "format", "Codec Format", OFFSET(format), AV_OPT_TYPE_INT, { .i64 = CODEC_JP2 }, CODEC_J2K, CODEC_JP2, VE, "format" },
00441 { "j2k", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = CODEC_J2K }, 0, 0, VE, "format" },
00442 { "jp2", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = CODEC_JP2 }, 0, 0, VE, "format" },
00443 { "profile", NULL, OFFSET(profile), AV_OPT_TYPE_INT, { .i64 = STD_RSIZ }, STD_RSIZ, CINEMA4K, VE, "profile" },
00444 { "jpeg2000", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = STD_RSIZ }, 0, 0, VE, "profile" },
00445 { "cinema2k", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = CINEMA2K }, 0, 0, VE, "profile" },
00446 { "cinema4k", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = CINEMA4K }, 0, 0, VE, "profile" },
00447 { "cinema_mode", "Digital Cinema", OFFSET(cinema_mode), AV_OPT_TYPE_INT, { .i64 = OFF }, OFF, CINEMA4K_24, VE, "cinema_mode" },
00448 { "off", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = OFF }, 0, 0, VE, "cinema_mode" },
00449 { "2k_24", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = CINEMA2K_24 }, 0, 0, VE, "cinema_mode" },
00450 { "2k_48", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = CINEMA2K_48 }, 0, 0, VE, "cinema_mode" },
00451 { "4k_24", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = CINEMA4K_24 }, 0, 0, VE, "cinema_mode" },
00452 { "prog_order", "Progression Order", OFFSET(prog_order), AV_OPT_TYPE_INT, { .i64 = LRCP }, LRCP, CPRL, VE, "prog_order" },
00453 { "lrcp", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = LRCP }, 0, 0, VE, "prog_order" },
00454 { "rlcp", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = RLCP }, 0, 0, VE, "prog_order" },
00455 { "rpcl", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = RPCL }, 0, 0, VE, "prog_order" },
00456 { "pcrl", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PCRL }, 0, 0, VE, "prog_order" },
00457 { "cprl", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = CPRL }, 0, 0, VE, "prog_order" },
00458 { "numresolution", NULL, OFFSET(numresolution), AV_OPT_TYPE_INT, { .i64 = 6 }, 1, INT_MAX, VE },
00459 { "numlayers", NULL, OFFSET(numlayers), AV_OPT_TYPE_INT, { .i64 = 1 }, 1, 10, VE },
00460 { "disto_alloc", NULL, OFFSET(disto_alloc), AV_OPT_TYPE_INT, { .i64 = 1 }, 0, 1, VE },
00461 { "fixed_alloc", NULL, OFFSET(fixed_alloc), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE },
00462 { "fixed_quality", NULL, OFFSET(fixed_quality), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE },
00463 { NULL },
00464 };
00465
00466 static const AVClass class = {
00467 .class_name = "libopenjpeg",
00468 .item_name = av_default_item_name,
00469 .option = options,
00470 .version = LIBAVUTIL_VERSION_INT,
00471 };
00472
00473 AVCodec ff_libopenjpeg_encoder = {
00474 .name = "libopenjpeg",
00475 .type = AVMEDIA_TYPE_VIDEO,
00476 .id = AV_CODEC_ID_JPEG2000,
00477 .priv_data_size = sizeof(LibOpenJPEGContext),
00478 .init = libopenjpeg_encode_init,
00479 .encode2 = libopenjpeg_encode_frame,
00480 .close = libopenjpeg_encode_close,
00481 .capabilities = 0,
00482 .pix_fmts = (const enum PixelFormat[]) {
00483 PIX_FMT_RGB24, PIX_FMT_RGBA, PIX_FMT_RGB48, PIX_FMT_RGBA64,
00484 PIX_FMT_GRAY8, PIX_FMT_GRAY8A, PIX_FMT_GRAY16,
00485 PIX_FMT_YUV420P, PIX_FMT_YUV422P, PIX_FMT_YUVA420P,
00486 PIX_FMT_YUV440P, PIX_FMT_YUV444P, PIX_FMT_YUVA422P,
00487 PIX_FMT_YUV411P, PIX_FMT_YUV410P, PIX_FMT_YUVA444P,
00488 PIX_FMT_YUV420P9, PIX_FMT_YUV422P9, PIX_FMT_YUV444P9,
00489 PIX_FMT_YUV420P10, PIX_FMT_YUV422P10, PIX_FMT_YUV444P10,
00490 PIX_FMT_YUV420P12, PIX_FMT_YUV422P12, PIX_FMT_YUV444P12,
00491 PIX_FMT_YUV420P14, PIX_FMT_YUV422P14, PIX_FMT_YUV444P14,
00492 PIX_FMT_YUV420P16, PIX_FMT_YUV422P16, PIX_FMT_YUV444P16,
00493 PIX_FMT_NONE
00494 },
00495 .long_name = NULL_IF_CONFIG_SMALL("OpenJPEG JPEG 2000"),
00496 .priv_class = &class,
00497 };