mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-02-09 14:14:39 +02:00
libopenjpegenc: stop reusing image data buffer for openjpeg 2
openjpeg 2 sets the data pointers of the image components to NULL, causing segfaults if the image is reused. Reviewed-by: Michael Bradshaw <mjbshaw@gmail.com> Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com> (cherry picked from commit 69c8505f3bf54f316e9dc8bec1c71dfa1febec63) Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
This commit is contained in:
parent
ada229e66f
commit
de42af2bee
@ -52,7 +52,9 @@
|
|||||||
|
|
||||||
typedef struct LibOpenJPEGContext {
|
typedef struct LibOpenJPEGContext {
|
||||||
AVClass *avclass;
|
AVClass *avclass;
|
||||||
|
#if OPENJPEG_MAJOR_VERSION == 1
|
||||||
opj_image_t *image;
|
opj_image_t *image;
|
||||||
|
#endif // OPENJPEG_MAJOR_VERSION == 1
|
||||||
opj_cparameters_t enc_params;
|
opj_cparameters_t enc_params;
|
||||||
#if OPENJPEG_MAJOR_VERSION == 1
|
#if OPENJPEG_MAJOR_VERSION == 1
|
||||||
opj_event_mgr_t event_mgr;
|
opj_event_mgr_t event_mgr;
|
||||||
@ -369,18 +371,22 @@ static av_cold int libopenjpeg_encode_init(AVCodecContext *avctx)
|
|||||||
cinema_parameters(&ctx->enc_params);
|
cinema_parameters(&ctx->enc_params);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if OPENJPEG_MAJOR_VERSION == 1
|
||||||
ctx->image = mj2_create_image(avctx, &ctx->enc_params);
|
ctx->image = mj2_create_image(avctx, &ctx->enc_params);
|
||||||
if (!ctx->image) {
|
if (!ctx->image) {
|
||||||
av_log(avctx, AV_LOG_ERROR, "Error creating the mj2 image\n");
|
av_log(avctx, AV_LOG_ERROR, "Error creating the mj2 image\n");
|
||||||
err = AVERROR(EINVAL);
|
err = AVERROR(EINVAL);
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
#endif // OPENJPEG_MAJOR_VERSION == 1
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
|
#if OPENJPEG_MAJOR_VERSION == 1
|
||||||
opj_image_destroy(ctx->image);
|
opj_image_destroy(ctx->image);
|
||||||
ctx->image = NULL;
|
ctx->image = NULL;
|
||||||
|
#endif // OPENJPEG_MAJOR_VERSION == 1
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -591,18 +597,24 @@ static int libopenjpeg_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
|
|||||||
const AVFrame *frame, int *got_packet)
|
const AVFrame *frame, int *got_packet)
|
||||||
{
|
{
|
||||||
LibOpenJPEGContext *ctx = avctx->priv_data;
|
LibOpenJPEGContext *ctx = avctx->priv_data;
|
||||||
opj_image_t *image = ctx->image;
|
int ret;
|
||||||
|
AVFrame *gbrframe;
|
||||||
|
int cpyresult = 0;
|
||||||
#if OPENJPEG_MAJOR_VERSION == 1
|
#if OPENJPEG_MAJOR_VERSION == 1
|
||||||
|
opj_image_t *image = ctx->image;
|
||||||
opj_cinfo_t *compress = NULL;
|
opj_cinfo_t *compress = NULL;
|
||||||
opj_cio_t *stream = NULL;
|
opj_cio_t *stream = NULL;
|
||||||
int len;
|
int len;
|
||||||
#else // OPENJPEG_MAJOR_VERSION == 2
|
#else // OPENJPEG_MAJOR_VERSION == 2
|
||||||
opj_codec_t *compress = NULL;
|
opj_codec_t *compress = NULL;
|
||||||
opj_stream_t *stream = NULL;
|
opj_stream_t *stream = NULL;
|
||||||
|
opj_image_t *image = mj2_create_image(avctx, &ctx->enc_params);
|
||||||
|
if (!image) {
|
||||||
|
av_log(avctx, AV_LOG_ERROR, "Error creating the mj2 image\n");
|
||||||
|
ret = AVERROR(EINVAL);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
#endif // OPENJPEG_MAJOR_VERSION == 1
|
#endif // OPENJPEG_MAJOR_VERSION == 1
|
||||||
int cpyresult = 0;
|
|
||||||
int ret;
|
|
||||||
AVFrame *gbrframe;
|
|
||||||
|
|
||||||
switch (avctx->pix_fmt) {
|
switch (avctx->pix_fmt) {
|
||||||
case AV_PIX_FMT_RGB24:
|
case AV_PIX_FMT_RGB24:
|
||||||
@ -625,8 +637,10 @@ static int libopenjpeg_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
|
|||||||
case AV_PIX_FMT_GBRP14:
|
case AV_PIX_FMT_GBRP14:
|
||||||
case AV_PIX_FMT_GBRP16:
|
case AV_PIX_FMT_GBRP16:
|
||||||
gbrframe = av_frame_clone(frame);
|
gbrframe = av_frame_clone(frame);
|
||||||
if (!gbrframe)
|
if (!gbrframe) {
|
||||||
return AVERROR(ENOMEM);
|
ret = AVERROR(ENOMEM);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
gbrframe->data[0] = frame->data[2]; // swap to be rgb
|
gbrframe->data[0] = frame->data[2]; // swap to be rgb
|
||||||
gbrframe->data[1] = frame->data[0];
|
gbrframe->data[1] = frame->data[0];
|
||||||
gbrframe->data[2] = frame->data[1];
|
gbrframe->data[2] = frame->data[1];
|
||||||
@ -683,19 +697,21 @@ static int libopenjpeg_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
|
|||||||
av_log(avctx, AV_LOG_ERROR,
|
av_log(avctx, AV_LOG_ERROR,
|
||||||
"The frame's pixel format '%s' is not supported\n",
|
"The frame's pixel format '%s' is not supported\n",
|
||||||
av_get_pix_fmt_name(avctx->pix_fmt));
|
av_get_pix_fmt_name(avctx->pix_fmt));
|
||||||
return AVERROR(EINVAL);
|
ret = AVERROR(EINVAL);
|
||||||
|
goto done;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!cpyresult) {
|
if (!cpyresult) {
|
||||||
av_log(avctx, AV_LOG_ERROR,
|
av_log(avctx, AV_LOG_ERROR,
|
||||||
"Could not copy the frame data to the internal image buffer\n");
|
"Could not copy the frame data to the internal image buffer\n");
|
||||||
return -1;
|
ret = -1;
|
||||||
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if OPENJPEG_MAJOR_VERSION == 2
|
#if OPENJPEG_MAJOR_VERSION == 2
|
||||||
if ((ret = ff_alloc_packet2(avctx, pkt, 1024, 0)) < 0) {
|
if ((ret = ff_alloc_packet2(avctx, pkt, 1024, 0)) < 0) {
|
||||||
return ret;
|
goto done;
|
||||||
}
|
}
|
||||||
#endif // OPENJPEG_MAJOR_VERSION == 2
|
#endif // OPENJPEG_MAJOR_VERSION == 2
|
||||||
|
|
||||||
@ -762,7 +778,7 @@ static int libopenjpeg_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
|
|||||||
#error Missing call to opj_stream_set_user_data
|
#error Missing call to opj_stream_set_user_data
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!opj_start_compress(compress, ctx->image, stream) ||
|
if (!opj_start_compress(compress, image, stream) ||
|
||||||
!opj_encode(compress, stream) ||
|
!opj_encode(compress, stream) ||
|
||||||
!opj_end_compress(compress, stream)) {
|
!opj_end_compress(compress, stream)) {
|
||||||
av_log(avctx, AV_LOG_ERROR, "Error during the opj encode\n");
|
av_log(avctx, AV_LOG_ERROR, "Error during the opj encode\n");
|
||||||
@ -781,6 +797,7 @@ done:
|
|||||||
#if OPENJPEG_MAJOR_VERSION == 2
|
#if OPENJPEG_MAJOR_VERSION == 2
|
||||||
opj_stream_destroy(stream);
|
opj_stream_destroy(stream);
|
||||||
opj_destroy_codec(compress);
|
opj_destroy_codec(compress);
|
||||||
|
opj_image_destroy(image);
|
||||||
#else
|
#else
|
||||||
opj_cio_close(stream);
|
opj_cio_close(stream);
|
||||||
opj_destroy_compress(compress);
|
opj_destroy_compress(compress);
|
||||||
@ -790,10 +807,12 @@ done:
|
|||||||
|
|
||||||
static av_cold int libopenjpeg_encode_close(AVCodecContext *avctx)
|
static av_cold int libopenjpeg_encode_close(AVCodecContext *avctx)
|
||||||
{
|
{
|
||||||
|
#if OPENJPEG_MAJOR_VERSION == 1
|
||||||
LibOpenJPEGContext *ctx = avctx->priv_data;
|
LibOpenJPEGContext *ctx = avctx->priv_data;
|
||||||
|
|
||||||
opj_image_destroy(ctx->image);
|
opj_image_destroy(ctx->image);
|
||||||
ctx->image = NULL;
|
ctx->image = NULL;
|
||||||
|
#endif // OPENJPEG_MAJOR_VERSION == 1
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user