summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libavcodec/libopenjpegenc.c102
1 files changed, 81 insertions, 21 deletions
diff --git a/libavcodec/libopenjpegenc.c b/libavcodec/libopenjpegenc.c
index 398339d74b..521583641e 100644
--- a/libavcodec/libopenjpegenc.c
+++ b/libavcodec/libopenjpegenc.c
@@ -53,7 +53,7 @@ static opj_image_t *mj2_create_image(AVCodecContext *avctx, opj_cparameters_t *p
opj_image_cmptparm_t *cmptparm;
opj_image_t *img;
int i;
- int bpp;
+ int bpp = 8;
int sub_dx[4];
int sub_dy[4];
int numcomps = 0;
@@ -68,37 +68,51 @@ static opj_image_t *mj2_create_image(AVCodecContext *avctx, opj_cparameters_t *p
case PIX_FMT_GRAY8:
color_space = CLRSPC_GRAY;
numcomps = 1;
- bpp = 8;
break;
case PIX_FMT_RGB24:
color_space = CLRSPC_SRGB;
numcomps = 3;
- bpp = 24;
break;
case PIX_FMT_RGBA:
color_space = CLRSPC_SRGB;
numcomps = 4;
- bpp = 32;
break;
case PIX_FMT_YUV420P:
color_space = CLRSPC_SYCC;
numcomps = 3;
- bpp = 12;
break;
case PIX_FMT_YUV422P:
color_space = CLRSPC_SYCC;
numcomps = 3;
- bpp = 16;
break;
case PIX_FMT_YUV440P:
color_space = CLRSPC_SYCC;
numcomps = 3;
- bpp = 16;
break;
case PIX_FMT_YUV444P:
color_space = CLRSPC_SYCC;
numcomps = 3;
- bpp = 24;
+ break;
+ case PIX_FMT_YUV420P9:
+ case PIX_FMT_YUV422P9:
+ case PIX_FMT_YUV444P9:
+ color_space = CLRSPC_SYCC;
+ numcomps = 3;
+ bpp = 9;
+ break;
+ case PIX_FMT_YUV420P10:
+ case PIX_FMT_YUV422P10:
+ case PIX_FMT_YUV444P10:
+ color_space = CLRSPC_SYCC;
+ numcomps = 3;
+ bpp = 10;
+ break;
+ case PIX_FMT_YUV420P16:
+ case PIX_FMT_YUV422P16:
+ case PIX_FMT_YUV444P16:
+ color_space = CLRSPC_SYCC;
+ numcomps = 3;
+ bpp = 16;
break;
default:
av_log(avctx, AV_LOG_ERROR, "The requested pixel format '%s' is not supported\n", av_get_pix_fmt_name(avctx->pix_fmt));
@@ -111,7 +125,7 @@ static opj_image_t *mj2_create_image(AVCodecContext *avctx, opj_cparameters_t *p
return NULL;
}
for (i = 0; i < numcomps; i++) {
- cmptparm[i].prec = 8;
+ cmptparm[i].prec = bpp;
cmptparm[i].bpp = bpp;
cmptparm[i].sgnd = 0;
cmptparm[i].dx = sub_dx[i];
@@ -131,7 +145,7 @@ static av_cold int libopenjpeg_encode_init(AVCodecContext *avctx)
opj_set_default_encoder_parameters(&ctx->enc_params);
ctx->enc_params.tcp_numlayers = 1;
- ctx->enc_params.tcp_rates[0] = FFMAX(avctx->compression_level, 0);
+ ctx->enc_params.tcp_rates[0] = FFMAX(avctx->compression_level, 0) * 2;
ctx->enc_params.cp_disto_alloc = 1;
ctx->compress = opj_create_compress(CODEC_J2K);
@@ -189,7 +203,7 @@ static int libopenjpeg_copy_rgba(AVCodecContext *avctx, AVFrame *frame, opj_imag
return 1;
}
-static int libopenjpeg_copy_yuv(AVCodecContext *avctx, AVFrame *frame, opj_image_t *image)
+static int libopenjpeg_copy_yuv8(AVCodecContext *avctx, AVFrame *frame, opj_image_t *image)
{
int compno;
int x;
@@ -217,6 +231,36 @@ static int libopenjpeg_copy_yuv(AVCodecContext *avctx, AVFrame *frame, opj_image
return 1;
}
+static int libopenjpeg_copy_yuv16(AVCodecContext *avctx, AVFrame *frame, opj_image_t *image)
+{
+ int compno;
+ int x;
+ int y;
+ int width;
+ int height;
+ const int numcomps = 3;
+ uint16_t *frame_ptr;
+
+ for (compno = 0; compno < numcomps; ++compno) {
+ if (image->comps[compno].w > frame->linesize[compno]) {
+ 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) {
+ for (x = 0; x < width; ++x) {
+ image->comps[compno].data[y * width + x] = frame_ptr[y * (frame->linesize[compno] / 2) + x];
+ }
+ }
+ }
+
+ return 1;
+}
+
static int libopenjpeg_encode_frame(AVCodecContext *avctx, uint8_t *buf, int buf_size, void *data)
{
AVFrame *frame = data;
@@ -248,7 +292,18 @@ static int libopenjpeg_encode_frame(AVCodecContext *avctx, uint8_t *buf, int buf
case PIX_FMT_YUV422P:
case PIX_FMT_YUV440P:
case PIX_FMT_YUV444P:
- cpyresult = libopenjpeg_copy_yuv(avctx, frame, image);
+ cpyresult = libopenjpeg_copy_yuv8(avctx, frame, image);
+ break;
+ case PIX_FMT_YUV420P9:
+ case PIX_FMT_YUV420P10:
+ case PIX_FMT_YUV420P16:
+ case PIX_FMT_YUV422P9:
+ case PIX_FMT_YUV422P10:
+ case PIX_FMT_YUV422P16:
+ case PIX_FMT_YUV444P9:
+ case PIX_FMT_YUV444P10:
+ case PIX_FMT_YUV444P16:
+ cpyresult = libopenjpeg_copy_yuv16(avctx, frame, image);
break;
default:
av_log(avctx, AV_LOG_ERROR, "The frame's pixel format '%s' is not supported\n", av_get_pix_fmt_name(avctx->pix_fmt));
@@ -298,15 +353,20 @@ static av_cold int libopenjpeg_encode_close(AVCodecContext *avctx)
AVCodec ff_libopenjpeg_encoder = {
- .name = "libopenjpeg",
- .type = AVMEDIA_TYPE_VIDEO,
- .id = CODEC_ID_JPEG2000,
+ .name = "libopenjpeg",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_JPEG2000,
.priv_data_size = sizeof(LibOpenJPEGContext),
- .init = libopenjpeg_encode_init,
- .encode = libopenjpeg_encode_frame,
- .close = libopenjpeg_encode_close,
- .decode = NULL,
- .capabilities = 0,
- .pix_fmts = (const enum PixelFormat[]){PIX_FMT_GRAY8,PIX_FMT_RGB24,PIX_FMT_RGBA,PIX_FMT_YUV420P,PIX_FMT_YUV422P,PIX_FMT_YUV440P,PIX_FMT_YUV444P},
+ .init = libopenjpeg_encode_init,
+ .encode = libopenjpeg_encode_frame,
+ .close = libopenjpeg_encode_close,
+ .decode = NULL,
+ .capabilities = 0,
+ .pix_fmts = (const enum PixelFormat[]){PIX_FMT_RGB24,PIX_FMT_RGBA,PIX_FMT_GRAY8,
+ PIX_FMT_YUV420P,PIX_FMT_YUV422P,
+ PIX_FMT_YUV440P,PIX_FMT_YUV444P,
+ PIX_FMT_YUV420P9,PIX_FMT_YUV422P9,PIX_FMT_YUV444P9,
+ PIX_FMT_YUV420P10,PIX_FMT_YUV422P10,PIX_FMT_YUV444P10,
+ PIX_FMT_YUV420P16,PIX_FMT_YUV422P16,PIX_FMT_YUV444P16},
.long_name = NULL_IF_CONFIG_SMALL("OpenJPEG based JPEG 2000 encoder"),
} ;