X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Fmxpegdec.c;h=a8ef6d0e0d64b132d9c92ea364996db653786c3f;hb=f6b85523692b0e7d4c4efb8449fa201d313424fe;hp=fd3fef47a909ba85c676882d2ed1a5834a9e130c;hpb=a18e04bcf989a9d7f5629c573f9d70f8a020c7a7;p=ffmpeg diff --git a/libavcodec/mxpegdec.c b/libavcodec/mxpegdec.c index fd3fef47a90..a8ef6d0e0d6 100644 --- a/libavcodec/mxpegdec.c +++ b/libavcodec/mxpegdec.c @@ -25,12 +25,13 @@ * MxPEG decoder */ +#include "internal.h" #include "mjpeg.h" #include "mjpegdec.h" typedef struct MXpegDecodeContext { MJpegDecodeContext jpg; - AVFrame picture[2]; /* pictures array */ + AVFrame *picture[2]; /* pictures array */ int picture_index; /* index of current picture */ int got_sof_data; /* true if SOF data successfully parsed */ int got_mxm_bitmask; /* true if MXM bitmask available */ @@ -41,12 +42,36 @@ typedef struct MXpegDecodeContext { unsigned mb_width, mb_height; /* size of picture in MB's from MXM header */ } MXpegDecodeContext; +static av_cold int mxpeg_decode_end(AVCodecContext *avctx) +{ + MXpegDecodeContext *s = avctx->priv_data; + MJpegDecodeContext *jpg = &s->jpg; + int i; + + jpg->picture_ptr = NULL; + ff_mjpeg_decode_end(avctx); + + for (i = 0; i < 2; ++i) + av_frame_free(&s->picture[i]); + + av_freep(&s->mxm_bitmask); + av_freep(&s->completion_bitmask); + + return 0; +} + static av_cold int mxpeg_decode_init(AVCodecContext *avctx) { MXpegDecodeContext *s = avctx->priv_data; - s->picture[0].reference = s->picture[1].reference = 3; - s->jpg.picture_ptr = &s->picture[0]; + s->picture[0] = av_frame_alloc(); + s->picture[1] = av_frame_alloc(); + if (!s->picture[0] || !s->picture[1]) { + mxpeg_decode_end(avctx); + return AVERROR(ENOMEM); + } + + s->jpg.picture_ptr = s->picture[0]; return ff_mjpeg_decode_init(avctx); } @@ -155,7 +180,7 @@ static int mxpeg_check_dimensions(MXpegDecodeContext *s, MJpegDecodeContext *jpg } static int mxpeg_decode_frame(AVCodecContext *avctx, - void *data, int *data_size, + void *data, int *got_frame, AVPacket *avpkt) { const uint8_t *buf = avpkt->data; @@ -166,7 +191,6 @@ static int mxpeg_decode_frame(AVCodecContext *avctx, const uint8_t *unescaped_buf_ptr; int unescaped_buf_size; int start_code; - AVFrame *picture = data; int ret; buf_ptr = buf; @@ -247,9 +271,9 @@ static int mxpeg_decode_frame(AVCodecContext *avctx, break; } /* use stored SOF data to allocate current picture */ - if (jpg->picture_ptr->data[0]) - avctx->release_buffer(avctx, jpg->picture_ptr); - if (avctx->get_buffer(avctx, jpg->picture_ptr) < 0) { + av_frame_unref(jpg->picture_ptr); + if (ff_get_buffer(avctx, jpg->picture_ptr, + AV_GET_BUFFER_FLAG_REF) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return AVERROR(ENOMEM); } @@ -262,23 +286,24 @@ static int mxpeg_decode_frame(AVCodecContext *avctx, } if (s->got_mxm_bitmask) { - AVFrame *reference_ptr = &s->picture[s->picture_index ^ 1]; + AVFrame *reference_ptr = s->picture[s->picture_index ^ 1]; if (mxpeg_check_dimensions(s, jpg, reference_ptr) < 0) break; /* allocate dummy reference picture if needed */ if (!reference_ptr->data[0] && - avctx->get_buffer(avctx, reference_ptr) < 0) { + ff_get_buffer(avctx, reference_ptr, + AV_GET_BUFFER_FLAG_REF) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return AVERROR(ENOMEM); } ret = ff_mjpeg_decode_sos(jpg, s->mxm_bitmask, reference_ptr); - if (ret < 0 && avctx->error_recognition >= FF_ER_EXPLODE) + if (ret < 0 && (avctx->err_recognition & AV_EF_EXPLODE)) return ret; } else { ret = ff_mjpeg_decode_sos(jpg, NULL, NULL); - if (ret < 0 && avctx->error_recognition >= FF_ER_EXPLODE) + if (ret < 0 && (avctx->err_recognition & AV_EF_EXPLODE)) return ret; } @@ -292,51 +317,34 @@ static int mxpeg_decode_frame(AVCodecContext *avctx, the_end: if (jpg->got_picture) { - *data_size = sizeof(AVFrame); - *picture = *jpg->picture_ptr; + int ret = av_frame_ref(data, jpg->picture_ptr); + if (ret < 0) + return ret; + *got_frame = 1; + s->picture_index ^= 1; - jpg->picture_ptr = &s->picture[s->picture_index]; + jpg->picture_ptr = s->picture[s->picture_index]; if (!s->has_complete_frame) { if (!s->got_mxm_bitmask) s->has_complete_frame = 1; else - *data_size = 0; + *got_frame = 0; } } return buf_ptr - buf; } -static av_cold int mxpeg_decode_end(AVCodecContext *avctx) -{ - MXpegDecodeContext *s = avctx->priv_data; - MJpegDecodeContext *jpg = &s->jpg; - int i; - - jpg->picture_ptr = NULL; - ff_mjpeg_decode_end(avctx); - - for (i = 0; i < 2; ++i) { - if (s->picture[i].data[0]) - avctx->release_buffer(avctx, &s->picture[i]); - } - - av_freep(&s->mxm_bitmask); - av_freep(&s->completion_bitmask); - - return 0; -} - AVCodec ff_mxpeg_decoder = { .name = "mxpeg", .long_name = NULL_IF_CONFIG_SMALL("Mobotix MxPEG video"), .type = AVMEDIA_TYPE_VIDEO, - .id = CODEC_ID_MXPEG, + .id = AV_CODEC_ID_MXPEG, .priv_data_size = sizeof(MXpegDecodeContext), .init = mxpeg_decode_init, .close = mxpeg_decode_end, .decode = mxpeg_decode_frame, - .capabilities = CODEC_CAP_DR1, - .max_lowres = 3 + .capabilities = AV_CODEC_CAP_DR1, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, };