X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Fmjpegdec.c;h=d8fc9defa308b8433ce9368f7fccbb07a52382bf;hb=380146924ecad2e05e9dcc5c3c2e1b5ba47c51e8;hp=1bcbcfd1d4e86a47d70c970ceb3cbae88ed465a3;hpb=1218777ffd152287244349d4ff9e1cbc84fa2c54;p=ffmpeg diff --git a/libavcodec/mjpegdec.c b/libavcodec/mjpegdec.c index 1bcbcfd1d4e..d8fc9defa30 100644 --- a/libavcodec/mjpegdec.c +++ b/libavcodec/mjpegdec.c @@ -30,16 +30,19 @@ * MJPEG decoder. */ -// #define DEBUG #include #include "libavutil/imgutils.h" #include "libavutil/opt.h" #include "avcodec.h" -#include "dsputil.h" +#include "blockdsp.h" +#include "idctdsp.h" +#include "internal.h" +#include "jpegtables.h" #include "mjpeg.h" #include "mjpegdec.h" #include "jpeglsdec.h" +#include "put_bits.h" static int build_vlc(VLC *vlc, const uint8_t *bits_table, @@ -85,18 +88,26 @@ av_cold int ff_mjpeg_decode_init(AVCodecContext *avctx) { MJpegDecodeContext *s = avctx->priv_data; - if (!s->picture_ptr) - s->picture_ptr = &s->picture; + if (!s->picture_ptr) { + s->picture = av_frame_alloc(); + if (!s->picture) + return AVERROR(ENOMEM); + s->picture_ptr = s->picture; + } s->avctx = avctx; - ff_dsputil_init(&s->dsp, avctx); - ff_init_scantable(s->dsp.idct_permutation, &s->scantable, ff_zigzag_direct); + ff_blockdsp_init(&s->bdsp, avctx); + ff_hpeldsp_init(&s->hdsp, avctx->flags); + ff_idctdsp_init(&s->idsp, avctx); + ff_init_scantable(s->idsp.idct_permutation, &s->scantable, + ff_zigzag_direct); s->buffer_size = 0; s->buffer = NULL; s->start_code = -1; s->first_picture = 1; s->org_height = avctx->coded_height; avctx->chroma_sample_location = AVCHROMA_LOC_CENTER; + avctx->colorspace = AVCOL_SPC_BT470BG; build_basic_mjpeg_vlc(s); @@ -211,18 +222,20 @@ int ff_mjpeg_decode_dht(MJpegDecodeContext *s) int ff_mjpeg_decode_sof(MJpegDecodeContext *s) { - int len, nb_components, i, width, height, pix_fmt_id; + int h_count[MAX_COMPONENTS] = { 0 }; + int v_count[MAX_COMPONENTS] = { 0 }; + int len, nb_components, i, width, height, bits, pix_fmt_id, ret; /* XXX: verify len field validity */ len = get_bits(&s->gb, 16); - s->bits = get_bits(&s->gb, 8); + bits = get_bits(&s->gb, 8); if (s->pegasus_rct) - s->bits = 9; - if (s->bits == 9 && !s->pegasus_rct) + bits = 9; + if (bits == 9 && !s->pegasus_rct) s->rct = 1; // FIXME ugly - if (s->bits != 8 && !s->lossless) { + if (bits != 8 && !s->lossless) { av_log(s->avctx, AV_LOG_ERROR, "only 8 bits/component accepted\n"); return -1; } @@ -242,10 +255,17 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s) if (nb_components <= 0 || nb_components > MAX_COMPONENTS) return -1; - if (s->ls && !(s->bits <= 8 || nb_components == 1)) { - av_log_missing_feature(s->avctx, - "only <= 8 bits/component or " - "16-bit gray accepted for JPEG-LS\n", 0); + if (s->interlaced && (s->bottom_field == !s->interlace_polarity)) { + if (nb_components != s->nb_components) { + av_log(s->avctx, AV_LOG_ERROR, + "nb_components changing in interlaced picture\n"); + return AVERROR_INVALIDDATA; + } + } + if (s->ls && !(bits <= 8 || nb_components == 1)) { + avpriv_report_missing_feature(s->avctx, + "JPEG-LS that is not <= 8 " + "bits/component or 16-bit gray"); return AVERROR_PATCHWELCOME; } s->nb_components = nb_components; @@ -254,24 +274,30 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s) for (i = 0; i < nb_components; i++) { /* component id */ s->component_id[i] = get_bits(&s->gb, 8) - 1; - s->h_count[i] = get_bits(&s->gb, 4); - s->v_count[i] = get_bits(&s->gb, 4); + h_count[i] = get_bits(&s->gb, 4); + v_count[i] = get_bits(&s->gb, 4); /* compute hmax and vmax (only used in interleaved case) */ - if (s->h_count[i] > s->h_max) - s->h_max = s->h_count[i]; - if (s->v_count[i] > s->v_max) - s->v_max = s->v_count[i]; + if (h_count[i] > s->h_max) + s->h_max = h_count[i]; + if (v_count[i] > s->v_max) + s->v_max = v_count[i]; s->quant_index[i] = get_bits(&s->gb, 8); if (s->quant_index[i] >= 4) return AVERROR_INVALIDDATA; + if (!h_count[i] || !v_count[i]) { + av_log(s->avctx, AV_LOG_ERROR, + "Invalid sampling factor in component %d %d:%d\n", + i, h_count[i], v_count[i]); + return AVERROR_INVALIDDATA; + } + av_log(s->avctx, AV_LOG_DEBUG, "component %d %d:%d id: %d quant:%d\n", - i, s->h_count[i], s->v_count[i], + i, h_count[i], v_count[i], s->component_id[i], s->quant_index[i]); } if (s->ls && (s->h_max > 1 || s->v_max > 1)) { - av_log_missing_feature(s->avctx, - "Subsampling in JPEG-LS is not supported.\n", 0); + avpriv_report_missing_feature(s->avctx, "Subsampling in JPEG-LS"); return AVERROR_PATCHWELCOME; } @@ -279,12 +305,14 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s) s->rgb = 1; /* if different size, realloc/alloc picture */ - /* XXX: also check h_count and v_count */ - if (width != s->width || height != s->height) { - av_freep(&s->qscale_table); - + if (width != s->width || height != s->height || bits != s->bits || + memcmp(s->h_count, h_count, sizeof(h_count)) || + memcmp(s->v_count, v_count, sizeof(v_count))) { s->width = width; s->height = height; + s->bits = bits; + memcpy(s->h_count, h_count, sizeof(h_count)); + memcpy(s->v_count, v_count, sizeof(v_count)); s->interlaced = 0; /* test interlaced mode */ @@ -298,9 +326,10 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s) height *= 2; } - avcodec_set_dimensions(s->avctx, width, height); + ret = ff_set_dimensions(s->avctx, width, height); + if (ret < 0) + return ret; - s->qscale_table = av_mallocz((s->width + 15) / 16); s->first_picture = 0; } @@ -321,22 +350,27 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s) switch (pix_fmt_id) { case 0x11111100: if (s->rgb) - s->avctx->pix_fmt = PIX_FMT_BGRA; - else - s->avctx->pix_fmt = s->cs_itu601 ? PIX_FMT_YUV444P : PIX_FMT_YUVJ444P; + s->avctx->pix_fmt = AV_PIX_FMT_BGRA; + else { + s->avctx->pix_fmt = s->cs_itu601 ? AV_PIX_FMT_YUV444P : AV_PIX_FMT_YUVJ444P; + s->avctx->color_range = s->cs_itu601 ? AVCOL_RANGE_MPEG : AVCOL_RANGE_JPEG; + } assert(s->nb_components == 3); break; case 0x11000000: - s->avctx->pix_fmt = PIX_FMT_GRAY8; + s->avctx->pix_fmt = AV_PIX_FMT_GRAY8; break; case 0x12111100: - s->avctx->pix_fmt = s->cs_itu601 ? PIX_FMT_YUV440P : PIX_FMT_YUVJ440P; + s->avctx->pix_fmt = s->cs_itu601 ? AV_PIX_FMT_YUV440P : AV_PIX_FMT_YUVJ440P; + s->avctx->color_range = s->cs_itu601 ? AVCOL_RANGE_MPEG : AVCOL_RANGE_JPEG; break; case 0x21111100: - s->avctx->pix_fmt = s->cs_itu601 ? PIX_FMT_YUV422P : PIX_FMT_YUVJ422P; + s->avctx->pix_fmt = s->cs_itu601 ? AV_PIX_FMT_YUV422P : AV_PIX_FMT_YUVJ422P; + s->avctx->color_range = s->cs_itu601 ? AVCOL_RANGE_MPEG : AVCOL_RANGE_JPEG; break; case 0x22111100: - s->avctx->pix_fmt = s->cs_itu601 ? PIX_FMT_YUV420P : PIX_FMT_YUVJ420P; + s->avctx->pix_fmt = s->cs_itu601 ? AV_PIX_FMT_YUV420P : AV_PIX_FMT_YUVJ420P; + s->avctx->color_range = s->cs_itu601 ? AVCOL_RANGE_MPEG : AVCOL_RANGE_JPEG; break; default: av_log(s->avctx, AV_LOG_ERROR, "Unhandled pixel format 0x%x\n", pix_fmt_id); @@ -344,17 +378,21 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s) } if (s->ls) { if (s->nb_components > 1) - s->avctx->pix_fmt = PIX_FMT_RGB24; + s->avctx->pix_fmt = AV_PIX_FMT_RGB24; else if (s->bits <= 8) - s->avctx->pix_fmt = PIX_FMT_GRAY8; + s->avctx->pix_fmt = AV_PIX_FMT_GRAY8; else - s->avctx->pix_fmt = PIX_FMT_GRAY16; + s->avctx->pix_fmt = AV_PIX_FMT_GRAY16; } - if (s->picture_ptr->data[0]) - s->avctx->release_buffer(s->avctx, s->picture_ptr); + s->pix_desc = av_pix_fmt_desc_get(s->avctx->pix_fmt); + if (!s->pix_desc) { + av_log(s->avctx, AV_LOG_ERROR, "Could not get a pixel format descriptor.\n"); + return AVERROR_BUG; + } - if (s->avctx->get_buffer(s->avctx, s->picture_ptr) < 0) { + av_frame_unref(s->picture_ptr); + if (ff_get_buffer(s->avctx, s->picture_ptr, AV_GET_BUFFER_FLAG_REF) < 0) { av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return -1; } @@ -365,7 +403,7 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s) for (i = 0; i < 3; i++) s->linesize[i] = s->picture_ptr->linesize[i] << s->interlaced; - av_dlog(s->avctx, "%d %d %d %d %d %d\n", + ff_dlog(s->avctx, "%d %d %d %d %d %d\n", s->width, s->height, s->linesize[0], s->linesize[1], s->interlaced, s->avctx->height); @@ -408,7 +446,7 @@ static inline int mjpeg_decode_dc(MJpegDecodeContext *s, int dc_index) } /* decode block and dequantize */ -static int decode_block(MJpegDecodeContext *s, DCTELEM *block, int component, +static int decode_block(MJpegDecodeContext *s, int16_t *block, int component, int dc_index, int ac_index, int16_t *quant_matrix) { int code, i, j, level, val; @@ -456,12 +494,12 @@ static int decode_block(MJpegDecodeContext *s, DCTELEM *block, int component, return 0; } -static int decode_dc_progressive(MJpegDecodeContext *s, DCTELEM *block, +static int decode_dc_progressive(MJpegDecodeContext *s, int16_t *block, int component, int dc_index, int16_t *quant_matrix, int Al) { int val; - s->dsp.clear_block(block); + s->bdsp.clear_block(block); val = mjpeg_decode_dc(s, dc_index); if (val == 0xffff) { av_log(s->avctx, AV_LOG_ERROR, "error dc\n"); @@ -474,7 +512,7 @@ static int decode_dc_progressive(MJpegDecodeContext *s, DCTELEM *block, } /* decode block and dequantize - progressive JPEG version */ -static int decode_block_progressive(MJpegDecodeContext *s, DCTELEM *block, +static int decode_block_progressive(MJpegDecodeContext *s, int16_t *block, uint8_t *last_nnz, int ac_index, int16_t *quant_matrix, int ss, int se, int Al, int *EOBRUN) @@ -572,7 +610,7 @@ for (; ; i++) { \ } /* decode block and dequantize - progressive JPEG refinement pass */ -static int decode_block_refinement(MJpegDecodeContext *s, DCTELEM *block, +static int decode_block_refinement(MJpegDecodeContext *s, int16_t *block, uint8_t *last_nnz, int ac_index, int16_t *quant_matrix, int ss, int se, int Al, int *EOBRUN) @@ -709,10 +747,9 @@ static int ljpeg_decode_rgb_scan(MJpegDecodeContext *s, int predictor, } static int ljpeg_decode_yuv_scan(MJpegDecodeContext *s, int predictor, - int point_transform) + int point_transform, int nb_components) { int i, mb_x, mb_y; - const int nb_components = 3; for (mb_y = 0; mb_y < s->mb_height; mb_y++) { for (mb_x = 0; mb_x < s->mb_width; mb_x++) { @@ -811,26 +848,12 @@ static int mjpeg_decode_scan(MJpegDecodeContext *s, int nb_components, int Ah, if (mb_bitmask) init_get_bits(&mb_bitmask_gb, mb_bitmask, s->mb_width * s->mb_height); - if (s->flipped && s->avctx->flags & CODEC_FLAG_EMU_EDGE) { - av_log(s->avctx, AV_LOG_ERROR, - "Can not flip image with CODEC_FLAG_EMU_EDGE set!\n"); - s->flipped = 0; - } - for (i = 0; i < nb_components; i++) { int c = s->comp_index[i]; data[c] = s->picture_ptr->data[c]; reference_data[c] = reference ? reference->data[c] : NULL; linesize[c] = s->linesize[c]; s->coefs_finished[c] |= 1; - if (s->flipped) { - // picture should be flipped upside-down for this codec - int offset = (linesize[c] * (s->v_scount[i] * - (8 * s->mb_height - ((s->height / s->v_max) & 7)) - 1)); - data[c] += offset; - reference_data[c] += offset; - linesize[c] *= -1; - } } for (mb_y = 0; mb_y < s->mb_height; mb_y++) { @@ -864,10 +887,11 @@ static int mjpeg_decode_scan(MJpegDecodeContext *s, int nb_components, int Ah, ptr = data[c] + block_offset; if (!s->progressive) { if (copy_mb) - copy_block8(ptr, reference_data[c] + block_offset, - linesize[c], linesize[c], 8); + s->hdsp.put_pixels_tab[1][0](ptr, + reference_data[c] + block_offset, + linesize[c], 8); else { - s->dsp.clear_block(s->block); + s->bdsp.clear_block(s->block); if (decode_block(s, s->block, i, s->dc_index[i], s->ac_index[i], s->quant_matrixes[s->quant_index[c]]) < 0) { @@ -875,12 +899,12 @@ static int mjpeg_decode_scan(MJpegDecodeContext *s, int nb_components, int Ah, "error y=%d x=%d\n", mb_y, mb_x); return AVERROR_INVALIDDATA; } - s->dsp.idct_put(ptr, linesize[c], s->block); + s->idsp.idct_put(ptr, linesize[c], s->block); } } else { int block_idx = s->block_stride[c] * (v * mb_y + y) + (h * mb_x + x); - DCTELEM *block = s->blocks[c][block_idx]; + int16_t *block = s->blocks[c][block_idx]; if (Ah) block[0] += get_bits1(&s->gb) * s->quant_matrixes[s->quant_index[c]][0] << Al; @@ -892,8 +916,8 @@ static int mjpeg_decode_scan(MJpegDecodeContext *s, int nb_components, int Ah, return AVERROR_INVALIDDATA; } } - av_dlog(s->avctx, "mb: %d %d processed\n", mb_y, mb_x); - av_dlog(s->avctx, "%d %d %d %d %d %d %d %d \n", + ff_dlog(s->avctx, "mb: %d %d processed\n", mb_y, mb_x); + ff_dlog(s->avctx, "%d %d %d %d %d %d %d %d \n", mb_x, mb_y, x, y, c, s->bottom_field, (v * mb_y + y) * 8, (h * mb_x + x) * 8); if (++x == h) { @@ -939,11 +963,18 @@ static int mjpeg_decode_scan_progressive_ac(MJpegDecodeContext *s, int ss, int16_t *quant_matrix = s->quant_matrixes[s->quant_index[c]]; GetBitContext mb_bitmask_gb; + if (ss < 0 || ss >= 64 || + se < ss || se >= 64 || + Ah < 0 || Al < 0) + return AVERROR_INVALIDDATA; + if (mb_bitmask) init_get_bits(&mb_bitmask_gb, mb_bitmask, s->mb_width * s->mb_height); if (!Al) { - s->coefs_finished[c] |= (1LL << (se + 1)) - (1LL << ss); + // s->coefs_finished is a bitmask for coefficients coded + // ss and se are parameters telling start and end coefficients + s->coefs_finished[c] |= (~0ULL >> (63 - (se - ss))) << ss; last_scan = !~s->coefs_finished[c]; } @@ -957,7 +988,7 @@ static int mjpeg_decode_scan_progressive_ac(MJpegDecodeContext *s, int ss, int block_offset = mb_y * linesize * 8; uint8_t *ptr = data + block_offset; int block_idx = mb_y * s->block_stride[c]; - DCTELEM (*block)[64] = &s->blocks[c][block_idx]; + int16_t (*block)[64] = &s->blocks[c][block_idx]; uint8_t *last_nnz = &s->last_nnz[c][block_idx]; for (mb_x = 0; mb_x < s->mb_width; mb_x++, block++, last_nnz++) { const int copy_mb = mb_bitmask && !get_bits1(&mb_bitmask_gb); @@ -979,10 +1010,11 @@ static int mjpeg_decode_scan_progressive_ac(MJpegDecodeContext *s, int ss, if (last_scan) { if (copy_mb) { - copy_block8(ptr, reference_data + block_offset, - linesize, linesize, 8); + s->hdsp.put_pixels_tab[1][0](ptr, + reference_data + block_offset, + linesize, 8); } else { - s->dsp.idct_put(ptr, linesize, *block); + s->idsp.idct_put(ptr, linesize, *block); ptr += 8; } } @@ -1094,7 +1126,8 @@ next_field: return ret; } else { if ((ret = ljpeg_decode_yuv_scan(s, predictor, - point_transform)) < 0) + point_transform, + nb_components)) < 0) return ret; } } @@ -1120,7 +1153,7 @@ next_field: GetBitContext bak = s->gb; align_get_bits(&bak); if (show_bits(&bak, 16) == 0xFFD1) { - av_dlog(s->avctx, "AVRn interlaced picture marker found\n"); + ff_dlog(s->avctx, "AVRn interlaced picture marker found\n"); s->gb = bak; skip_bits(&s->gb, 16); s->bottom_field ^= 1; @@ -1202,6 +1235,7 @@ static int mjpeg_decode_app(MJpegDecodeContext *s) s->avctx->sample_aspect_ratio.num = get_bits(&s->gb, 16); s->avctx->sample_aspect_ratio.den = get_bits(&s->gb, 16); + ff_set_sar(s->avctx, s->avctx->sample_aspect_ratio); if (s->avctx->debug & FF_DEBUG_PICT_INFO) av_log(s->avctx, AV_LOG_INFO, @@ -1347,7 +1381,7 @@ static int find_marker(const uint8_t **pbuf_ptr, const uint8_t *buf_end) } val = -1; found: - av_dlog(NULL, "find_marker skipped %d bytes\n", skipped); + ff_dlog(NULL, "find_marker skipped %d bytes\n", skipped); *pbuf_ptr = buf_ptr; return val; } @@ -1387,6 +1421,8 @@ int ff_mjpeg_find_marker(MJpegDecodeContext *s, } *unescaped_buf_ptr = s->buffer; *unescaped_buf_size = dst - s->buffer; + memset(s->buffer + *unescaped_buf_size, 0, + AV_INPUT_BUFFER_PADDING_SIZE); av_log(s->avctx, AV_LOG_DEBUG, "escaping removed %td bytes\n", (buf_end - *buf_ptr) - (dst - s->buffer)); @@ -1428,6 +1464,8 @@ int ff_mjpeg_find_marker(MJpegDecodeContext *s, *unescaped_buf_ptr = dst; *unescaped_buf_size = (bit_count + 7) >> 3; + memset(s->buffer + *unescaped_buf_size, 0, + AV_INPUT_BUFFER_PADDING_SIZE); } else { *unescaped_buf_ptr = *buf_ptr; *unescaped_buf_size = buf_end - *buf_ptr; @@ -1436,9 +1474,10 @@ int ff_mjpeg_find_marker(MJpegDecodeContext *s, return start_code; } -int ff_mjpeg_decode_frame(AVCodecContext *avctx, void *data, int *data_size, +int ff_mjpeg_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { + AVFrame *frame = data; const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; MJpegDecodeContext *s = avctx->priv_data; @@ -1447,7 +1486,6 @@ int ff_mjpeg_decode_frame(AVCodecContext *avctx, void *data, int *data_size, int unescaped_buf_size; int start_code; int ret = 0; - AVFrame *picture = data; s->got_picture = 0; // picture from previous image can not be reused buf_ptr = buf; @@ -1460,153 +1498,167 @@ int ff_mjpeg_decode_frame(AVCodecContext *avctx, void *data, int *data_size, /* EOF */ if (start_code < 0) { goto the_end; - } else if (unescaped_buf_size > (1U<<29)) { - av_log(avctx, AV_LOG_ERROR, "MJPEG packet 0x%x too big (0x%x/0x%x), corrupt data?\n", + } else if (unescaped_buf_size > INT_MAX / 8) { + av_log(avctx, AV_LOG_ERROR, + "MJPEG packet 0x%x too big (%d/%d), corrupt data?\n", start_code, unescaped_buf_size, buf_size); return AVERROR_INVALIDDATA; - } else { - av_log(avctx, AV_LOG_DEBUG, "marker=%x avail_size_in_buf=%td\n", - start_code, buf_end - buf_ptr); + } + + av_log(avctx, AV_LOG_DEBUG, "marker=%x avail_size_in_buf=%td\n", + start_code, buf_end - buf_ptr); - init_get_bits(&s->gb, unescaped_buf_ptr, unescaped_buf_size * 8); + ret = init_get_bits(&s->gb, unescaped_buf_ptr, + unescaped_buf_size * 8); + if (ret < 0) + return ret; - s->start_code = start_code; - if (s->avctx->debug & FF_DEBUG_STARTCODE) - av_log(avctx, AV_LOG_DEBUG, "startcode: %X\n", start_code); + s->start_code = start_code; + if (s->avctx->debug & FF_DEBUG_STARTCODE) + av_log(avctx, AV_LOG_DEBUG, "startcode: %X\n", start_code); - /* process markers */ - if (start_code >= 0xd0 && start_code <= 0xd7) - av_log(avctx, AV_LOG_DEBUG, - "restart marker: %d\n", start_code & 0x0f); - /* APP fields */ - else if (start_code >= APP0 && start_code <= APP15) - mjpeg_decode_app(s); - /* Comment */ - else if (start_code == COM) - mjpeg_decode_com(s); - - switch (start_code) { - case SOI: - s->restart_interval = 0; - s->restart_count = 0; - /* nothing to do on SOI */ + /* process markers */ + if (start_code >= 0xd0 && start_code <= 0xd7) + av_log(avctx, AV_LOG_DEBUG, + "restart marker: %d\n", start_code & 0x0f); + /* APP fields */ + else if (start_code >= APP0 && start_code <= APP15) + mjpeg_decode_app(s); + /* Comment */ + else if (start_code == COM) + mjpeg_decode_com(s); + + if (!CONFIG_JPEGLS_DECODER && + (start_code == SOF48 || start_code == LSE)) { + av_log(avctx, AV_LOG_ERROR, "JPEG-LS support not enabled.\n"); + return AVERROR(ENOSYS); + } + + switch (start_code) { + case SOI: + s->restart_interval = 0; + s->restart_count = 0; + /* nothing to do on SOI */ + break; + case DQT: + ff_mjpeg_decode_dqt(s); + break; + case DHT: + if ((ret = ff_mjpeg_decode_dht(s)) < 0) { + av_log(avctx, AV_LOG_ERROR, "huffman table decode error\n"); + return ret; + } + break; + case SOF0: + case SOF1: + s->lossless = 0; + s->ls = 0; + s->progressive = 0; + if ((ret = ff_mjpeg_decode_sof(s)) < 0) + return ret; + break; + case SOF2: + s->lossless = 0; + s->ls = 0; + s->progressive = 1; + if ((ret = ff_mjpeg_decode_sof(s)) < 0) + return ret; + break; + case SOF3: + s->lossless = 1; + s->ls = 0; + s->progressive = 0; + if ((ret = ff_mjpeg_decode_sof(s)) < 0) + return ret; + break; + case SOF48: + s->lossless = 1; + s->ls = 1; + s->progressive = 0; + if ((ret = ff_mjpeg_decode_sof(s)) < 0) + return ret; + break; + case LSE: + if (!CONFIG_JPEGLS_DECODER || + (ret = ff_jpegls_decode_lse(s)) < 0) + return ret; + break; + case EOI: + s->cur_scan = 0; + if ((s->buggy_avid && !s->interlaced) || s->restart_interval) break; - case DQT: - ff_mjpeg_decode_dqt(s); +eoi_parser: + if (!s->got_picture) { + av_log(avctx, AV_LOG_WARNING, + "Found EOI before any SOF, ignoring\n"); break; - case DHT: - if ((ret = ff_mjpeg_decode_dht(s)) < 0) { - av_log(avctx, AV_LOG_ERROR, "huffman table decode error\n"); - return ret; + } + if (s->interlaced) { + s->bottom_field ^= 1; + /* if not bottom field, do not output image yet */ + if (s->bottom_field == !s->interlace_polarity) + goto not_the_end; + } + if ((ret = av_frame_ref(frame, s->picture_ptr)) < 0) + return ret; + if (s->flipped) { + int i; + for (i = 0; frame->data[i]; i++) { + int h = frame->height >> ((i == 1 || i == 2) ? + s->pix_desc->log2_chroma_h : 0); + frame->data[i] += frame->linesize[i] * (h - 1); + frame->linesize[i] *= -1; } - break; - case SOF0: - case SOF1: - s->lossless = 0; - s->ls = 0; - s->progressive = 0; - if ((ret = ff_mjpeg_decode_sof(s)) < 0) - return ret; - break; - case SOF2: - s->lossless = 0; - s->ls = 0; - s->progressive = 1; - if ((ret = ff_mjpeg_decode_sof(s)) < 0) - return ret; - break; - case SOF3: - s->lossless = 1; - s->ls = 0; - s->progressive = 0; - if ((ret = ff_mjpeg_decode_sof(s)) < 0) - return ret; - break; - case SOF48: - s->lossless = 1; - s->ls = 1; - s->progressive = 0; - if ((ret = ff_mjpeg_decode_sof(s)) < 0) - return ret; - break; - case LSE: - if (!CONFIG_JPEGLS_DECODER || - (ret = ff_jpegls_decode_lse(s)) < 0) - return ret; - break; - case EOI: - s->cur_scan = 0; - if ((s->buggy_avid && !s->interlaced) || s->restart_interval) - break; -eoi_parser: - if (!s->got_picture) { - av_log(avctx, AV_LOG_WARNING, - "Found EOI before any SOF, ignoring\n"); - break; - } - if (s->interlaced) { - s->bottom_field ^= 1; - /* if not bottom field, do not output image yet */ - if (s->bottom_field == !s->interlace_polarity) - goto not_the_end; - } - *picture = *s->picture_ptr; - *data_size = sizeof(AVFrame); - - if (!s->lossless) { - picture->quality = FFMAX3(s->qscale[0], - s->qscale[1], - s->qscale[2]); - picture->qstride = 0; - picture->qscale_table = s->qscale_table; - memset(picture->qscale_table, picture->quality, - (s->width + 15) / 16); - if (avctx->debug & FF_DEBUG_QP) - av_log(avctx, AV_LOG_DEBUG, - "QP: %d\n", picture->quality); - picture->quality *= FF_QP2LAMBDA; - } + } + *got_frame = 1; - goto the_end; - case SOS: - if (!s->got_picture) { - av_log(avctx, AV_LOG_WARNING, - "Can not process SOS before SOF, skipping\n"); - break; - } - if ((ret = ff_mjpeg_decode_sos(s, NULL, NULL)) < 0 && - (avctx->err_recognition & AV_EF_EXPLODE)) - return ret; - /* buggy avid puts EOI every 10-20th frame */ - /* if restart period is over process EOI */ - if ((s->buggy_avid && !s->interlaced) || s->restart_interval) - goto eoi_parser; - break; - case DRI: - mjpeg_decode_dri(s); - break; - case SOF5: - case SOF6: - case SOF7: - case SOF9: - case SOF10: - case SOF11: - case SOF13: - case SOF14: - case SOF15: - case JPG: - av_log(avctx, AV_LOG_ERROR, - "mjpeg: unsupported coding type (%x)\n", start_code); - break; + if (!s->lossless && + avctx->debug & FF_DEBUG_QP) { + av_log(avctx, AV_LOG_DEBUG, + "QP: %d\n", FFMAX3(s->qscale[0], + s->qscale[1], + s->qscale[2])); } -not_the_end: - /* eof process start code */ - buf_ptr += (get_bits_count(&s->gb) + 7) / 8; - av_log(avctx, AV_LOG_DEBUG, - "marker parser used %d bytes (%d bits)\n", - (get_bits_count(&s->gb) + 7) / 8, get_bits_count(&s->gb)); + goto the_end; + case SOS: + if (!s->got_picture) { + av_log(avctx, AV_LOG_WARNING, + "Can not process SOS before SOF, skipping\n"); + break; + } + if ((ret = ff_mjpeg_decode_sos(s, NULL, NULL)) < 0 && + (avctx->err_recognition & AV_EF_EXPLODE)) + return ret; + /* buggy avid puts EOI every 10-20th frame */ + /* if restart period is over process EOI */ + if ((s->buggy_avid && !s->interlaced) || s->restart_interval) + goto eoi_parser; + break; + case DRI: + mjpeg_decode_dri(s); + break; + case SOF5: + case SOF6: + case SOF7: + case SOF9: + case SOF10: + case SOF11: + case SOF13: + case SOF14: + case SOF15: + case JPG: + av_log(avctx, AV_LOG_ERROR, + "mjpeg: unsupported coding type (%x)\n", start_code); + break; } + +not_the_end: + /* eof process start code */ + buf_ptr += (get_bits_count(&s->gb) + 7) / 8; + av_log(avctx, AV_LOG_DEBUG, + "marker parser used %d bytes (%d bits)\n", + (get_bits_count(&s->gb) + 7) / 8, get_bits_count(&s->gb)); } if (s->got_picture) { av_log(avctx, AV_LOG_WARNING, "EOI missing, emulating\n"); @@ -1626,11 +1678,13 @@ av_cold int ff_mjpeg_decode_end(AVCodecContext *avctx) MJpegDecodeContext *s = avctx->priv_data; int i, j; - if (s->picture_ptr && s->picture_ptr->data[0]) - avctx->release_buffer(avctx, s->picture_ptr); + if (s->picture) { + av_frame_free(&s->picture); + s->picture_ptr = NULL; + } else if (s->picture_ptr) + av_frame_unref(s->picture_ptr); av_free(s->buffer); - av_free(s->qscale_table); av_freep(&s->ljpeg_buffer); s->ljpeg_buffer_size = 0; @@ -1662,25 +1716,27 @@ static const AVClass mjpegdec_class = { AVCodec ff_mjpeg_decoder = { .name = "mjpeg", + .long_name = NULL_IF_CONFIG_SMALL("MJPEG (Motion JPEG)"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_MJPEG, .priv_data_size = sizeof(MJpegDecodeContext), .init = ff_mjpeg_decode_init, .close = ff_mjpeg_decode_end, .decode = ff_mjpeg_decode_frame, - .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("MJPEG (Motion JPEG)"), + .capabilities = AV_CODEC_CAP_DR1, .priv_class = &mjpegdec_class, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, }; AVCodec ff_thp_decoder = { .name = "thp", + .long_name = NULL_IF_CONFIG_SMALL("Nintendo Gamecube THP video"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_THP, .priv_data_size = sizeof(MJpegDecodeContext), .init = ff_mjpeg_decode_init, .close = ff_mjpeg_decode_end, .decode = ff_mjpeg_decode_frame, - .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Nintendo Gamecube THP video"), + .capabilities = AV_CODEC_CAP_DR1, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, };