]> git.sesse.net Git - ffmpeg/blob - libavcodec/libopenjpegenc.c
Merge commit 'b57a95d0147beae746db1c1223d100447f42dced'
[ffmpeg] / libavcodec / libopenjpegenc.c
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/avassert.h"
28 #include "libavutil/common.h"
29 #include "libavutil/imgutils.h"
30 #include "libavutil/intreadwrite.h"
31 #include "libavutil/opt.h"
32 #include "avcodec.h"
33 #include "internal.h"
34
35 #if HAVE_OPENJPEG_2_3_OPENJPEG_H
36 #  include <openjpeg-2.3/openjpeg.h>
37 #elif HAVE_OPENJPEG_2_2_OPENJPEG_H
38 #  include <openjpeg-2.2/openjpeg.h>
39 #elif HAVE_OPENJPEG_2_1_OPENJPEG_H
40 #  include <openjpeg-2.1/openjpeg.h>
41 #elif HAVE_OPENJPEG_2_0_OPENJPEG_H
42 #  include <openjpeg-2.0/openjpeg.h>
43 #elif HAVE_OPENJPEG_1_5_OPENJPEG_H
44 #  include <openjpeg-1.5/openjpeg.h>
45 #else
46 #  include <openjpeg.h>
47 #endif
48
49 #if HAVE_OPENJPEG_2_3_OPENJPEG_H || HAVE_OPENJPEG_2_2_OPENJPEG_H || HAVE_OPENJPEG_2_1_OPENJPEG_H || HAVE_OPENJPEG_2_0_OPENJPEG_H
50 #  define OPENJPEG_MAJOR_VERSION 2
51 #  define OPJ(x) OPJ_##x
52 #else
53 #  define OPENJPEG_MAJOR_VERSION 1
54 #  define OPJ(x) x
55 #endif
56
57 typedef struct LibOpenJPEGContext {
58     AVClass *avclass;
59 #if OPENJPEG_MAJOR_VERSION == 1
60     opj_image_t *image;
61 #endif // OPENJPEG_MAJOR_VERSION == 1
62     opj_cparameters_t enc_params;
63 #if OPENJPEG_MAJOR_VERSION == 1
64     opj_event_mgr_t event_mgr;
65 #endif // OPENJPEG_MAJOR_VERSION == 1
66     int format;
67     int profile;
68     int prog_order;
69     int cinema_mode;
70     int numresolution;
71     int irreversible;
72     int disto_alloc;
73     int fixed_quality;
74 } LibOpenJPEGContext;
75
76 static void error_callback(const char *msg, void *data)
77 {
78     av_log(data, AV_LOG_ERROR, "%s\n", msg);
79 }
80
81 static void warning_callback(const char *msg, void *data)
82 {
83     av_log(data, AV_LOG_WARNING, "%s\n", msg);
84 }
85
86 static void info_callback(const char *msg, void *data)
87 {
88     av_log(data, AV_LOG_DEBUG, "%s\n", msg);
89 }
90
91 #if OPENJPEG_MAJOR_VERSION == 2
92 typedef struct PacketWriter {
93     int pos;
94     AVPacket *packet;
95 } PacketWriter;
96
97 static OPJ_SIZE_T stream_write(void *out_buffer, OPJ_SIZE_T nb_bytes, void *user_data)
98 {
99     PacketWriter *writer = user_data;
100     AVPacket *packet = writer->packet;
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     memcpy(packet->data + writer->pos, out_buffer, nb_bytes);
113     writer->pos += (int)nb_bytes;
114     return nb_bytes;
115 }
116
117 static OPJ_OFF_T stream_skip(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         if (writer->pos == 0) {
123             return (OPJ_SIZE_T)-1;
124         }
125         if (nb_bytes + writer->pos < 0) {
126             nb_bytes = -writer->pos;
127         }
128     } else {
129         int remaining = packet->size - writer->pos;
130         if (nb_bytes > remaining) {
131             OPJ_SIZE_T needed = nb_bytes - remaining;
132             int max_growth = INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE - packet->size;
133             if (needed > max_growth) {
134                 return (OPJ_SIZE_T)-1;
135             }
136             if (av_grow_packet(packet, (int)needed)) {
137                 return (OPJ_SIZE_T)-1;
138             }
139         }
140     }
141     writer->pos += (int)nb_bytes;
142     return nb_bytes;
143 }
144
145 static OPJ_BOOL stream_seek(OPJ_OFF_T nb_bytes, void *user_data)
146 {
147     PacketWriter *writer = user_data;
148     AVPacket *packet = writer->packet;
149     if (nb_bytes < 0) {
150         return OPJ_FALSE;
151     }
152     if (nb_bytes > packet->size) {
153         if (nb_bytes > INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE ||
154             av_grow_packet(packet, (int)nb_bytes - packet->size)) {
155             return OPJ_FALSE;
156         }
157     }
158     writer->pos = (int)nb_bytes;
159     return OPJ_TRUE;
160 }
161 #endif // OPENJPEG_MAJOR_VERSION == 2
162
163 static void cinema_parameters(opj_cparameters_t *p)
164 {
165     p->tile_size_on = 0;
166     p->cp_tdx = 1;
167     p->cp_tdy = 1;
168
169     /* Tile part */
170     p->tp_flag = 'C';
171     p->tp_on = 1;
172
173     /* Tile and Image shall be at (0, 0) */
174     p->cp_tx0 = 0;
175     p->cp_ty0 = 0;
176     p->image_offset_x0 = 0;
177     p->image_offset_y0 = 0;
178
179     /* Codeblock size= 32 * 32 */
180     p->cblockw_init = 32;
181     p->cblockh_init = 32;
182     p->csty |= 0x01;
183
184     /* The progression order shall be CPRL */
185     p->prog_order = OPJ(CPRL);
186
187     /* No ROI */
188     p->roi_compno = -1;
189
190     /* No subsampling */
191     p->subsampling_dx = 1;
192     p->subsampling_dy = 1;
193
194     /* 9-7 transform */
195     p->irreversible = 1;
196
197     p->tcp_mct = 1;
198 }
199
200 static opj_image_t *mj2_create_image(AVCodecContext *avctx, opj_cparameters_t *parameters)
201 {
202     const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt);
203     opj_image_cmptparm_t cmptparm[4] = {{0}};
204     opj_image_t *img;
205     int i;
206     int sub_dx[4];
207     int sub_dy[4];
208     int numcomps;
209     OPJ_COLOR_SPACE color_space = OPJ(CLRSPC_UNKNOWN);
210
211     sub_dx[0] = sub_dx[3] = 1;
212     sub_dy[0] = sub_dy[3] = 1;
213     sub_dx[1] = sub_dx[2] = 1 << desc->log2_chroma_w;
214     sub_dy[1] = sub_dy[2] = 1 << desc->log2_chroma_h;
215
216     numcomps = desc->nb_components;
217
218     switch (avctx->pix_fmt) {
219     case AV_PIX_FMT_GRAY8:
220     case AV_PIX_FMT_YA8:
221     case AV_PIX_FMT_GRAY16:
222     case AV_PIX_FMT_YA16:
223         color_space = OPJ(CLRSPC_GRAY);
224         break;
225     case AV_PIX_FMT_RGB24:
226     case AV_PIX_FMT_RGBA:
227     case AV_PIX_FMT_RGB48:
228     case AV_PIX_FMT_RGBA64:
229     case AV_PIX_FMT_GBR24P:
230     case AV_PIX_FMT_GBRP9:
231     case AV_PIX_FMT_GBRP10:
232     case AV_PIX_FMT_GBRP12:
233     case AV_PIX_FMT_GBRP14:
234     case AV_PIX_FMT_GBRP16:
235     case AV_PIX_FMT_XYZ12:
236         color_space = OPJ(CLRSPC_SRGB);
237         break;
238     case AV_PIX_FMT_YUV410P:
239     case AV_PIX_FMT_YUV411P:
240     case AV_PIX_FMT_YUV420P:
241     case AV_PIX_FMT_YUV422P:
242     case AV_PIX_FMT_YUV440P:
243     case AV_PIX_FMT_YUV444P:
244     case AV_PIX_FMT_YUVA420P:
245     case AV_PIX_FMT_YUVA422P:
246     case AV_PIX_FMT_YUVA444P:
247     case AV_PIX_FMT_YUV420P9:
248     case AV_PIX_FMT_YUV422P9:
249     case AV_PIX_FMT_YUV444P9:
250     case AV_PIX_FMT_YUVA420P9:
251     case AV_PIX_FMT_YUVA422P9:
252     case AV_PIX_FMT_YUVA444P9:
253     case AV_PIX_FMT_YUV420P10:
254     case AV_PIX_FMT_YUV422P10:
255     case AV_PIX_FMT_YUV444P10:
256     case AV_PIX_FMT_YUVA420P10:
257     case AV_PIX_FMT_YUVA422P10:
258     case AV_PIX_FMT_YUVA444P10:
259     case AV_PIX_FMT_YUV420P12:
260     case AV_PIX_FMT_YUV422P12:
261     case AV_PIX_FMT_YUV444P12:
262     case AV_PIX_FMT_YUV420P14:
263     case AV_PIX_FMT_YUV422P14:
264     case AV_PIX_FMT_YUV444P14:
265     case AV_PIX_FMT_YUV420P16:
266     case AV_PIX_FMT_YUV422P16:
267     case AV_PIX_FMT_YUV444P16:
268     case AV_PIX_FMT_YUVA420P16:
269     case AV_PIX_FMT_YUVA422P16:
270     case AV_PIX_FMT_YUVA444P16:
271         color_space = OPJ(CLRSPC_SYCC);
272         break;
273     default:
274         av_log(avctx, AV_LOG_ERROR,
275                "The requested pixel format '%s' is not supported\n",
276                av_get_pix_fmt_name(avctx->pix_fmt));
277         return NULL;
278     }
279
280     for (i = 0; i < numcomps; i++) {
281         cmptparm[i].prec = desc->comp[i].depth;
282         cmptparm[i].bpp  = desc->comp[i].depth;
283         cmptparm[i].sgnd = 0;
284         cmptparm[i].dx = sub_dx[i];
285         cmptparm[i].dy = sub_dy[i];
286         cmptparm[i].w = (avctx->width + sub_dx[i] - 1) / sub_dx[i];
287         cmptparm[i].h = (avctx->height + sub_dy[i] - 1) / sub_dy[i];
288     }
289
290     img = opj_image_create(numcomps, cmptparm, color_space);
291
292     if (!img)
293         return NULL;
294
295     // x0, y0 is the top left corner of the image
296     // x1, y1 is the width, height of the reference grid
297     img->x0 = 0;
298     img->y0 = 0;
299     img->x1 = (avctx->width  - 1) * parameters->subsampling_dx + 1;
300     img->y1 = (avctx->height - 1) * parameters->subsampling_dy + 1;
301
302     return img;
303 }
304
305 static av_cold int libopenjpeg_encode_init(AVCodecContext *avctx)
306 {
307     LibOpenJPEGContext *ctx = avctx->priv_data;
308     int err = 0;
309
310     opj_set_default_encoder_parameters(&ctx->enc_params);
311
312 #if HAVE_OPENJPEG_2_3_OPENJPEG_H || HAVE_OPENJPEG_2_2_OPENJPEG_H || HAVE_OPENJPEG_2_1_OPENJPEG_H
313     switch (ctx->cinema_mode) {
314     case OPJ_CINEMA2K_24:
315         ctx->enc_params.rsiz = OPJ_PROFILE_CINEMA_2K;
316         ctx->enc_params.max_cs_size = OPJ_CINEMA_24_CS;
317         ctx->enc_params.max_comp_size = OPJ_CINEMA_24_COMP;
318         break;
319     case OPJ_CINEMA2K_48:
320         ctx->enc_params.rsiz = OPJ_PROFILE_CINEMA_2K;
321         ctx->enc_params.max_cs_size = OPJ_CINEMA_48_CS;
322         ctx->enc_params.max_comp_size = OPJ_CINEMA_48_COMP;
323         break;
324     case OPJ_CINEMA4K_24:
325         ctx->enc_params.rsiz = OPJ_PROFILE_CINEMA_4K;
326         ctx->enc_params.max_cs_size = OPJ_CINEMA_24_CS;
327         ctx->enc_params.max_comp_size = OPJ_CINEMA_24_COMP;
328         break;
329     }
330
331     switch (ctx->profile) {
332     case OPJ_CINEMA2K:
333         if (ctx->enc_params.rsiz == OPJ_PROFILE_CINEMA_4K) {
334             err = AVERROR(EINVAL);
335             break;
336         }
337         ctx->enc_params.rsiz = OPJ_PROFILE_CINEMA_2K;
338         break;
339     case OPJ_CINEMA4K:
340         if (ctx->enc_params.rsiz == OPJ_PROFILE_CINEMA_2K) {
341             err = AVERROR(EINVAL);
342             break;
343         }
344         ctx->enc_params.rsiz = OPJ_PROFILE_CINEMA_4K;
345         break;
346     }
347
348     if (err) {
349         av_log(avctx, AV_LOG_ERROR,
350                "Invalid parameter pairing: cinema_mode and profile conflict.\n");
351         goto fail;
352     }
353 #else
354     ctx->enc_params.cp_rsiz = ctx->profile;
355     ctx->enc_params.cp_cinema = ctx->cinema_mode;
356 #endif
357
358     if (!ctx->numresolution) {
359         ctx->numresolution = 6;
360         while (FFMIN(avctx->width, avctx->height) >> ctx->numresolution < 1)
361             ctx->numresolution --;
362     }
363
364     ctx->enc_params.prog_order = ctx->prog_order;
365     ctx->enc_params.numresolution = ctx->numresolution;
366     ctx->enc_params.irreversible = ctx->irreversible;
367     ctx->enc_params.cp_disto_alloc = ctx->disto_alloc;
368     ctx->enc_params.cp_fixed_quality = ctx->fixed_quality;
369     ctx->enc_params.tcp_numlayers = 1;
370     ctx->enc_params.tcp_rates[0] = FFMAX(avctx->compression_level, 0) * 2;
371
372     if (ctx->cinema_mode > 0) {
373         cinema_parameters(&ctx->enc_params);
374     }
375
376 #if OPENJPEG_MAJOR_VERSION == 1
377     ctx->image = mj2_create_image(avctx, &ctx->enc_params);
378     if (!ctx->image) {
379         av_log(avctx, AV_LOG_ERROR, "Error creating the mj2 image\n");
380         err = AVERROR(EINVAL);
381         goto fail;
382     }
383 #endif // OPENJPEG_MAJOR_VERSION == 1
384
385     return 0;
386
387 fail:
388 #if OPENJPEG_MAJOR_VERSION == 1
389     opj_image_destroy(ctx->image);
390     ctx->image = NULL;
391 #endif // OPENJPEG_MAJOR_VERSION == 1
392     return err;
393 }
394
395 static int libopenjpeg_copy_packed8(AVCodecContext *avctx, const AVFrame *frame, opj_image_t *image)
396 {
397     int compno;
398     int x;
399     int y;
400     int *image_line;
401     int frame_index;
402     const int numcomps = image->numcomps;
403
404     for (compno = 0; compno < numcomps; ++compno) {
405         if (image->comps[compno].w > frame->linesize[0] / numcomps) {
406             av_log(avctx, AV_LOG_ERROR, "Error: frame's linesize is too small for the image\n");
407             return 0;
408         }
409     }
410
411     for (compno = 0; compno < numcomps; ++compno) {
412         for (y = 0; y < avctx->height; ++y) {
413             image_line = image->comps[compno].data + y * image->comps[compno].w;
414             frame_index = y * frame->linesize[0] + compno;
415             for (x = 0; x < avctx->width; ++x) {
416                 image_line[x] = frame->data[0][frame_index];
417                 frame_index += numcomps;
418             }
419             for (; x < image->comps[compno].w; ++x) {
420                 image_line[x] = image_line[x - 1];
421             }
422         }
423         for (; y < image->comps[compno].h; ++y) {
424             image_line = image->comps[compno].data + y * image->comps[compno].w;
425             for (x = 0; x < image->comps[compno].w; ++x) {
426                 image_line[x] = image_line[x - (int)image->comps[compno].w];
427             }
428         }
429     }
430
431     return 1;
432 }
433
434 // for XYZ 12 bit
435 static int libopenjpeg_copy_packed12(AVCodecContext *avctx, const AVFrame *frame, opj_image_t *image)
436 {
437     int compno;
438     int x, y;
439     int *image_line;
440     int frame_index;
441     const int numcomps  = image->numcomps;
442     uint16_t *frame_ptr = (uint16_t *)frame->data[0];
443
444     for (compno = 0; compno < numcomps; ++compno) {
445         if (image->comps[compno].w > frame->linesize[0] / numcomps) {
446             av_log(avctx, AV_LOG_ERROR, "Error: frame's linesize is too small for the image\n");
447             return 0;
448         }
449     }
450
451     for (compno = 0; compno < numcomps; ++compno) {
452         for (y = 0; y < avctx->height; ++y) {
453             image_line = image->comps[compno].data + y * image->comps[compno].w;
454             frame_index = y * (frame->linesize[0] / 2) + compno;
455             for (x = 0; x < avctx->width; ++x) {
456                 image_line[x] = frame_ptr[frame_index] >> 4;
457                 frame_index += numcomps;
458             }
459             for (; x < image->comps[compno].w; ++x) {
460                 image_line[x] = image_line[x - 1];
461             }
462         }
463         for (; y < image->comps[compno].h; ++y) {
464             image_line = image->comps[compno].data + y * image->comps[compno].w;
465             for (x = 0; x < image->comps[compno].w; ++x) {
466                 image_line[x] = image_line[x - (int)image->comps[compno].w];
467             }
468         }
469     }
470
471     return 1;
472 }
473
474 static int libopenjpeg_copy_packed16(AVCodecContext *avctx, const AVFrame *frame, opj_image_t *image)
475 {
476     int compno;
477     int x;
478     int y;
479     int *image_line;
480     int frame_index;
481     const int numcomps = image->numcomps;
482     uint16_t *frame_ptr = (uint16_t*)frame->data[0];
483
484     for (compno = 0; compno < numcomps; ++compno) {
485         if (image->comps[compno].w > frame->linesize[0] / numcomps) {
486             av_log(avctx, AV_LOG_ERROR, "Error: frame's linesize is too small for the image\n");
487             return 0;
488         }
489     }
490
491     for (compno = 0; compno < numcomps; ++compno) {
492         for (y = 0; y < avctx->height; ++y) {
493             image_line = image->comps[compno].data + y * image->comps[compno].w;
494             frame_index = y * (frame->linesize[0] / 2) + compno;
495             for (x = 0; x < avctx->width; ++x) {
496                 image_line[x] = frame_ptr[frame_index];
497                 frame_index += numcomps;
498             }
499             for (; x < image->comps[compno].w; ++x) {
500                 image_line[x] = image_line[x - 1];
501             }
502         }
503         for (; y < image->comps[compno].h; ++y) {
504             image_line = image->comps[compno].data + y * image->comps[compno].w;
505             for (x = 0; x < image->comps[compno].w; ++x) {
506                 image_line[x] = image_line[x - (int)image->comps[compno].w];
507             }
508         }
509     }
510
511     return 1;
512 }
513
514 static int libopenjpeg_copy_unpacked8(AVCodecContext *avctx, const AVFrame *frame, opj_image_t *image)
515 {
516     int compno;
517     int x;
518     int y;
519     int width;
520     int height;
521     int *image_line;
522     int frame_index;
523     const int numcomps = image->numcomps;
524
525     for (compno = 0; compno < numcomps; ++compno) {
526         if (image->comps[compno].w > frame->linesize[compno]) {
527             av_log(avctx, AV_LOG_ERROR, "Error: frame's linesize is too small for the image\n");
528             return 0;
529         }
530     }
531
532     for (compno = 0; compno < numcomps; ++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 * frame->linesize[compno];
538             for (x = 0; x < width; ++x)
539                 image_line[x] = frame->data[compno][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
555 static int libopenjpeg_copy_unpacked16(AVCodecContext *avctx, const AVFrame *frame, opj_image_t *image)
556 {
557     int compno;
558     int x;
559     int y;
560     int width;
561     int height;
562     int *image_line;
563     int frame_index;
564     const int numcomps = image->numcomps;
565     uint16_t *frame_ptr;
566
567     for (compno = 0; compno < numcomps; ++compno) {
568         if (image->comps[compno].w > frame->linesize[compno]) {
569             av_log(avctx, AV_LOG_ERROR, "Error: frame's linesize is too small for the image\n");
570             return 0;
571         }
572     }
573
574     for (compno = 0; compno < numcomps; ++compno) {
575         width     = (avctx->width + image->comps[compno].dx - 1) / image->comps[compno].dx;
576         height    = (avctx->height + image->comps[compno].dy - 1) / image->comps[compno].dy;
577         frame_ptr = (uint16_t *)frame->data[compno];
578         for (y = 0; y < height; ++y) {
579             image_line = image->comps[compno].data + y * image->comps[compno].w;
580             frame_index = y * (frame->linesize[compno] / 2);
581             for (x = 0; x < width; ++x)
582                 image_line[x] = frame_ptr[frame_index++];
583             for (; x < image->comps[compno].w; ++x) {
584                 image_line[x] = image_line[x - 1];
585             }
586         }
587         for (; y < image->comps[compno].h; ++y) {
588             image_line = image->comps[compno].data + y * image->comps[compno].w;
589             for (x = 0; x < image->comps[compno].w; ++x) {
590                 image_line[x] = image_line[x - (int)image->comps[compno].w];
591             }
592         }
593     }
594
595     return 1;
596 }
597
598 static int libopenjpeg_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
599                                     const AVFrame *frame, int *got_packet)
600 {
601     LibOpenJPEGContext *ctx = avctx->priv_data;
602     int ret;
603     AVFrame *gbrframe;
604     int cpyresult = 0;
605 #if OPENJPEG_MAJOR_VERSION == 1
606     opj_image_t *image      = ctx->image;
607     opj_cinfo_t *compress   = NULL;
608     opj_cio_t *stream       = NULL;
609     int len;
610 #else // OPENJPEG_MAJOR_VERSION == 2
611     PacketWriter writer     = { 0 };
612     opj_codec_t *compress   = NULL;
613     opj_stream_t *stream    = NULL;
614     opj_image_t *image      = mj2_create_image(avctx, &ctx->enc_params);
615     if (!image) {
616         av_log(avctx, AV_LOG_ERROR, "Error creating the mj2 image\n");
617         ret = AVERROR(EINVAL);
618         goto done;
619     }
620 #endif // OPENJPEG_MAJOR_VERSION == 1
621
622     switch (avctx->pix_fmt) {
623     case AV_PIX_FMT_RGB24:
624     case AV_PIX_FMT_RGBA:
625     case AV_PIX_FMT_YA8:
626         cpyresult = libopenjpeg_copy_packed8(avctx, frame, image);
627         break;
628     case AV_PIX_FMT_XYZ12:
629         cpyresult = libopenjpeg_copy_packed12(avctx, frame, image);
630         break;
631     case AV_PIX_FMT_RGB48:
632     case AV_PIX_FMT_RGBA64:
633     case AV_PIX_FMT_YA16:
634         cpyresult = libopenjpeg_copy_packed16(avctx, frame, image);
635         break;
636     case AV_PIX_FMT_GBR24P:
637     case AV_PIX_FMT_GBRP9:
638     case AV_PIX_FMT_GBRP10:
639     case AV_PIX_FMT_GBRP12:
640     case AV_PIX_FMT_GBRP14:
641     case AV_PIX_FMT_GBRP16:
642         gbrframe = av_frame_clone(frame);
643         if (!gbrframe) {
644             ret = AVERROR(ENOMEM);
645             goto done;
646         }
647         gbrframe->data[0] = frame->data[2]; // swap to be rgb
648         gbrframe->data[1] = frame->data[0];
649         gbrframe->data[2] = frame->data[1];
650         gbrframe->linesize[0] = frame->linesize[2];
651         gbrframe->linesize[1] = frame->linesize[0];
652         gbrframe->linesize[2] = frame->linesize[1];
653         if (avctx->pix_fmt == AV_PIX_FMT_GBR24P) {
654             cpyresult = libopenjpeg_copy_unpacked8(avctx, gbrframe, image);
655         } else {
656             cpyresult = libopenjpeg_copy_unpacked16(avctx, gbrframe, image);
657         }
658         av_frame_free(&gbrframe);
659         break;
660     case AV_PIX_FMT_GRAY8:
661     case AV_PIX_FMT_YUV410P:
662     case AV_PIX_FMT_YUV411P:
663     case AV_PIX_FMT_YUV420P:
664     case AV_PIX_FMT_YUV422P:
665     case AV_PIX_FMT_YUV440P:
666     case AV_PIX_FMT_YUV444P:
667     case AV_PIX_FMT_YUVA420P:
668     case AV_PIX_FMT_YUVA422P:
669     case AV_PIX_FMT_YUVA444P:
670         cpyresult = libopenjpeg_copy_unpacked8(avctx, frame, image);
671         break;
672     case AV_PIX_FMT_GRAY16:
673     case AV_PIX_FMT_YUV420P9:
674     case AV_PIX_FMT_YUV422P9:
675     case AV_PIX_FMT_YUV444P9:
676     case AV_PIX_FMT_YUVA420P9:
677     case AV_PIX_FMT_YUVA422P9:
678     case AV_PIX_FMT_YUVA444P9:
679     case AV_PIX_FMT_YUV444P10:
680     case AV_PIX_FMT_YUV422P10:
681     case AV_PIX_FMT_YUV420P10:
682     case AV_PIX_FMT_YUVA444P10:
683     case AV_PIX_FMT_YUVA422P10:
684     case AV_PIX_FMT_YUVA420P10:
685     case AV_PIX_FMT_YUV420P12:
686     case AV_PIX_FMT_YUV422P12:
687     case AV_PIX_FMT_YUV444P12:
688     case AV_PIX_FMT_YUV420P14:
689     case AV_PIX_FMT_YUV422P14:
690     case AV_PIX_FMT_YUV444P14:
691     case AV_PIX_FMT_YUV444P16:
692     case AV_PIX_FMT_YUV422P16:
693     case AV_PIX_FMT_YUV420P16:
694     case AV_PIX_FMT_YUVA444P16:
695     case AV_PIX_FMT_YUVA422P16:
696     case AV_PIX_FMT_YUVA420P16:
697         cpyresult = libopenjpeg_copy_unpacked16(avctx, frame, image);
698         break;
699     default:
700         av_log(avctx, AV_LOG_ERROR,
701                "The frame's pixel format '%s' is not supported\n",
702                av_get_pix_fmt_name(avctx->pix_fmt));
703         ret = AVERROR(EINVAL);
704         goto done;
705         break;
706     }
707
708     if (!cpyresult) {
709         av_log(avctx, AV_LOG_ERROR,
710                "Could not copy the frame data to the internal image buffer\n");
711         ret = -1;
712         goto done;
713     }
714
715 #if OPENJPEG_MAJOR_VERSION == 2
716     if ((ret = ff_alloc_packet2(avctx, pkt, 1024, 0)) < 0) {
717         goto done;
718     }
719 #endif // OPENJPEG_MAJOR_VERSION == 2
720
721     compress = opj_create_compress(ctx->format);
722     if (!compress) {
723         av_log(avctx, AV_LOG_ERROR, "Error creating the compressor\n");
724         ret = AVERROR(ENOMEM);
725         goto done;
726     }
727
728 #if OPENJPEG_MAJOR_VERSION == 1
729     opj_setup_encoder(compress, &ctx->enc_params, image);
730     stream = opj_cio_open((opj_common_ptr) compress, NULL, 0);
731 #else // OPENJPEG_MAJOR_VERSION == 2
732     if (!opj_set_error_handler(compress, error_callback, avctx) ||
733         !opj_set_warning_handler(compress, warning_callback, avctx) ||
734         !opj_set_info_handler(compress, info_callback, avctx)) {
735         av_log(avctx, AV_LOG_ERROR, "Error setting the compressor handlers\n");
736         ret = AVERROR_EXTERNAL;
737         goto done;
738     }
739
740     if (!opj_setup_encoder(compress, &ctx->enc_params, image)) {
741         av_log(avctx, AV_LOG_ERROR, "Error setting up the compressor\n");
742         ret = AVERROR_EXTERNAL;
743         goto done;
744     }
745     stream = opj_stream_default_create(OPJ_STREAM_WRITE);
746 #endif // OPENJPEG_MAJOR_VERSION == 1
747
748     if (!stream) {
749         av_log(avctx, AV_LOG_ERROR, "Error creating the cio stream\n");
750         ret = AVERROR(ENOMEM);
751         goto done;
752     }
753 #if OPENJPEG_MAJOR_VERSION == 1
754     memset(&ctx->event_mgr, 0, sizeof(ctx->event_mgr));
755     ctx->event_mgr.info_handler    = info_callback;
756     ctx->event_mgr.error_handler   = error_callback;
757     ctx->event_mgr.warning_handler = warning_callback;
758     opj_set_event_mgr((opj_common_ptr) compress, &ctx->event_mgr, avctx);
759     if (!opj_encode(compress, stream, image, NULL)) {
760         av_log(avctx, AV_LOG_ERROR, "Error during the opj encode\n");
761         ret = AVERROR_EXTERNAL;
762         goto done;
763     }
764
765     len = cio_tell(stream);
766     if ((ret = ff_alloc_packet2(avctx, pkt, len, 0)) < 0) {
767         goto done;
768     }
769
770     memcpy(pkt->data, stream->buffer, len);
771 #else // OPENJPEG_MAJOR_VERSION == 2
772     writer.packet = pkt;
773     opj_stream_set_write_function(stream, stream_write);
774     opj_stream_set_skip_function(stream, stream_skip);
775     opj_stream_set_seek_function(stream, stream_seek);
776 #if HAVE_OPENJPEG_2_3_OPENJPEG_H || HAVE_OPENJPEG_2_2_OPENJPEG_H || HAVE_OPENJPEG_2_1_OPENJPEG_H
777     opj_stream_set_user_data(stream, &writer, NULL);
778 #elif HAVE_OPENJPEG_2_0_OPENJPEG_H
779     opj_stream_set_user_data(stream, &writer);
780 #else
781 #error Missing call to opj_stream_set_user_data
782 #endif
783
784     if (!opj_start_compress(compress, image, stream) ||
785         !opj_encode(compress, stream) ||
786         !opj_end_compress(compress, stream)) {
787         av_log(avctx, AV_LOG_ERROR, "Error during the opj encode\n");
788         ret = AVERROR_EXTERNAL;
789         goto done;
790     }
791
792     av_shrink_packet(pkt, writer.pos);
793 #endif // OPENJPEG_MAJOR_VERSION == 1
794
795     pkt->flags |= AV_PKT_FLAG_KEY;
796     *got_packet = 1;
797     ret = 0;
798
799 done:
800 #if OPENJPEG_MAJOR_VERSION == 2
801     opj_stream_destroy(stream);
802     opj_destroy_codec(compress);
803     opj_image_destroy(image);
804 #else
805     opj_cio_close(stream);
806     opj_destroy_compress(compress);
807 #endif
808     return ret;
809 }
810
811 static av_cold int libopenjpeg_encode_close(AVCodecContext *avctx)
812 {
813 #if OPENJPEG_MAJOR_VERSION == 1
814     LibOpenJPEGContext *ctx = avctx->priv_data;
815
816     opj_image_destroy(ctx->image);
817     ctx->image = NULL;
818 #endif // OPENJPEG_MAJOR_VERSION == 1
819     return 0;
820 }
821
822 #define OFFSET(x) offsetof(LibOpenJPEGContext, x)
823 #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
824 static const AVOption options[] = {
825     { "format",        "Codec Format",      OFFSET(format),        AV_OPT_TYPE_INT,   { .i64 = OPJ(CODEC_JP2)   }, OPJ(CODEC_J2K), OPJ(CODEC_JP2),   VE, "format"      },
826     { "j2k",           NULL,                0,                     AV_OPT_TYPE_CONST, { .i64 = OPJ(CODEC_J2K)   }, 0,         0,           VE, "format"      },
827     { "jp2",           NULL,                0,                     AV_OPT_TYPE_CONST, { .i64 = OPJ(CODEC_JP2)   }, 0,         0,           VE, "format"      },
828     { "profile",       NULL,                OFFSET(profile),       AV_OPT_TYPE_INT,   { .i64 = OPJ(STD_RSIZ)    }, OPJ(STD_RSIZ),  OPJ(CINEMA4K),    VE, "profile"     },
829     { "jpeg2000",      NULL,                0,                     AV_OPT_TYPE_CONST, { .i64 = OPJ(STD_RSIZ)    }, 0,         0,           VE, "profile"     },
830     { "cinema2k",      NULL,                0,                     AV_OPT_TYPE_CONST, { .i64 = OPJ(CINEMA2K)    }, 0,         0,           VE, "profile"     },
831     { "cinema4k",      NULL,                0,                     AV_OPT_TYPE_CONST, { .i64 = OPJ(CINEMA4K)    }, 0,         0,           VE, "profile"     },
832     { "cinema_mode",   "Digital Cinema",    OFFSET(cinema_mode),   AV_OPT_TYPE_INT,   { .i64 = OPJ(OFF)         }, OPJ(OFF),       OPJ(CINEMA4K_24), VE, "cinema_mode" },
833     { "off",           NULL,                0,                     AV_OPT_TYPE_CONST, { .i64 = OPJ(OFF)         }, 0,         0,           VE, "cinema_mode" },
834     { "2k_24",         NULL,                0,                     AV_OPT_TYPE_CONST, { .i64 = OPJ(CINEMA2K_24) }, 0,         0,           VE, "cinema_mode" },
835     { "2k_48",         NULL,                0,                     AV_OPT_TYPE_CONST, { .i64 = OPJ(CINEMA2K_48) }, 0,         0,           VE, "cinema_mode" },
836     { "4k_24",         NULL,                0,                     AV_OPT_TYPE_CONST, { .i64 = OPJ(CINEMA4K_24) }, 0,         0,           VE, "cinema_mode" },
837     { "prog_order",    "Progression Order", OFFSET(prog_order),    AV_OPT_TYPE_INT,   { .i64 = OPJ(LRCP)    }, OPJ(LRCP),  OPJ(CPRL),    VE, "prog_order"  },
838     { "lrcp",          NULL,                0,                     AV_OPT_TYPE_CONST, { .i64 = OPJ(LRCP)    }, 0,         0,           VE, "prog_order"  },
839     { "rlcp",          NULL,                0,                     AV_OPT_TYPE_CONST, { .i64 = OPJ(RLCP)    }, 0,         0,           VE, "prog_order"  },
840     { "rpcl",          NULL,                0,                     AV_OPT_TYPE_CONST, { .i64 = OPJ(RPCL)    }, 0,         0,           VE, "prog_order"  },
841     { "pcrl",          NULL,                0,                     AV_OPT_TYPE_CONST, { .i64 = OPJ(PCRL)    }, 0,         0,           VE, "prog_order"  },
842     { "cprl",          NULL,                0,                     AV_OPT_TYPE_CONST, { .i64 = OPJ(CPRL)    }, 0,         0,           VE, "prog_order"  },
843     { "numresolution", NULL,                OFFSET(numresolution), AV_OPT_TYPE_INT,   { .i64 = 6            }, 0,         33,          VE                },
844     { "irreversible",  NULL,                OFFSET(irreversible),  AV_OPT_TYPE_INT,   { .i64 = 0            }, 0,         1,           VE                },
845     { "disto_alloc",   NULL,                OFFSET(disto_alloc),   AV_OPT_TYPE_INT,   { .i64 = 1            }, 0,         1,           VE                },
846     { "fixed_quality", NULL,                OFFSET(fixed_quality), AV_OPT_TYPE_INT,   { .i64 = 0            }, 0,         1,           VE                },
847     { NULL },
848 };
849
850 static const AVClass openjpeg_class = {
851     .class_name = "libopenjpeg",
852     .item_name  = av_default_item_name,
853     .option     = options,
854     .version    = LIBAVUTIL_VERSION_INT,
855 };
856
857 AVCodec ff_libopenjpeg_encoder = {
858     .name           = "libopenjpeg",
859     .long_name      = NULL_IF_CONFIG_SMALL("OpenJPEG JPEG 2000"),
860     .type           = AVMEDIA_TYPE_VIDEO,
861     .id             = AV_CODEC_ID_JPEG2000,
862     .priv_data_size = sizeof(LibOpenJPEGContext),
863     .init           = libopenjpeg_encode_init,
864     .encode2        = libopenjpeg_encode_frame,
865     .close          = libopenjpeg_encode_close,
866     .capabilities   = AV_CODEC_CAP_FRAME_THREADS | AV_CODEC_CAP_INTRA_ONLY,
867     .pix_fmts       = (const enum AVPixelFormat[]) {
868         AV_PIX_FMT_RGB24, AV_PIX_FMT_RGBA, AV_PIX_FMT_RGB48,
869         AV_PIX_FMT_RGBA64, AV_PIX_FMT_GBR24P,
870         AV_PIX_FMT_GBRP9, AV_PIX_FMT_GBRP10, AV_PIX_FMT_GBRP12, AV_PIX_FMT_GBRP14, AV_PIX_FMT_GBRP16,
871         AV_PIX_FMT_GRAY8, AV_PIX_FMT_YA8, AV_PIX_FMT_GRAY16, AV_PIX_FMT_YA16,
872         AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUVA420P,
873         AV_PIX_FMT_YUV440P, AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUVA422P,
874         AV_PIX_FMT_YUV411P, AV_PIX_FMT_YUV410P, AV_PIX_FMT_YUVA444P,
875         AV_PIX_FMT_YUV420P9, AV_PIX_FMT_YUV422P9, AV_PIX_FMT_YUV444P9,
876         AV_PIX_FMT_YUVA420P9, AV_PIX_FMT_YUVA422P9, AV_PIX_FMT_YUVA444P9,
877         AV_PIX_FMT_YUV420P10, AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUV444P10,
878         AV_PIX_FMT_YUVA420P10, AV_PIX_FMT_YUVA422P10, AV_PIX_FMT_YUVA444P10,
879         AV_PIX_FMT_YUV420P12, AV_PIX_FMT_YUV422P12, AV_PIX_FMT_YUV444P12,
880         AV_PIX_FMT_YUV420P14, AV_PIX_FMT_YUV422P14, AV_PIX_FMT_YUV444P14,
881         AV_PIX_FMT_YUV420P16, AV_PIX_FMT_YUV422P16, AV_PIX_FMT_YUV444P16,
882         AV_PIX_FMT_YUVA420P16, AV_PIX_FMT_YUVA422P16, AV_PIX_FMT_YUVA444P16,
883         AV_PIX_FMT_XYZ12,
884         AV_PIX_FMT_NONE
885     },
886     .priv_class     = &openjpeg_class,
887 };