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