X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Fmjpegdec.c;h=1f36b393a8e6e99064a1966aabe3d459f1855109;hb=081961f819c0b16c7a860d7da7d39f1fd91bd2f0;hp=896fa996f0865277afd4799fbedc4d1b5e75d5e1;hpb=a030279a67ef883df8cf3707774656fa1be81078;p=ffmpeg diff --git a/libavcodec/mjpegdec.c b/libavcodec/mjpegdec.c index 896fa996f08..1f36b393a8e 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 "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,19 +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_blockdsp_init(&s->bdsp, avctx); ff_hpeldsp_init(&s->hdsp, avctx->flags); - ff_dsputil_init(&s->dsp, avctx); - ff_init_scantable(s->dsp.idct_permutation, &s->scantable, ff_zigzag_direct); + 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); @@ -130,9 +140,9 @@ int ff_mjpeg_decode_dqt(MJpegDecodeContext *s) len = get_bits(&s->gb, 16) - 2; while (len >= 65) { - /* only 8 bit precision handled */ + /* only 8-bit precision handled */ if (get_bits(&s->gb, 4) != 0) { - av_log(s->avctx, AV_LOG_ERROR, "dqt: 16bit precision\n"); + av_log(s->avctx, AV_LOG_ERROR, "dqt: 16-bit precision\n"); return -1; } index = get_bits(&s->gb, 4); @@ -145,7 +155,7 @@ int ff_mjpeg_decode_dqt(MJpegDecodeContext *s) s->quant_matrixes[index][j] = get_bits(&s->gb, 8); } - // XXX FIXME finetune, and perhaps add dc too + // XXX FIXME fine-tune, and perhaps add dc too s->qscale[index] = FFMAX(s->quant_matrixes[index][s->scantable.permutated[1]], s->quant_matrixes[index][s->scantable.permutated[8]]) >> 1; av_log(s->avctx, AV_LOG_DEBUG, "qscale[%d]: %d\n", @@ -212,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; } @@ -243,7 +255,14 @@ 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)) { + 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"); @@ -255,25 +274,25 @@ 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 (!s->h_count[i] || !s->v_count[i]) { + if (!h_count[i] || !v_count[i]) { av_log(s->avctx, AV_LOG_ERROR, "Invalid sampling factor in component %d %d:%d\n", - i, s->h_count[i], s->v_count[i]); + 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]); } @@ -286,10 +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) { + 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 */ @@ -303,7 +326,9 @@ 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->first_picture = 0; } @@ -326,8 +351,10 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s) case 0x11111100: if (s->rgb) s->avctx->pix_fmt = AV_PIX_FMT_BGRA; - else + 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: @@ -335,12 +362,15 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s) break; case 0x12111100: 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 ? 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 ? 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); @@ -355,6 +385,12 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s) s->avctx->pix_fmt = AV_PIX_FMT_GRAY16; } + 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; + } + 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"); @@ -367,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); @@ -463,7 +499,7 @@ static int decode_dc_progressive(MJpegDecodeContext *s, int16_t *block, 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"); @@ -812,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++) { @@ -869,7 +891,7 @@ static int mjpeg_decode_scan(MJpegDecodeContext *s, int nb_components, int Ah, 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) { @@ -877,7 +899,7 @@ 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) + @@ -894,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) { @@ -941,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]; } @@ -985,7 +1014,7 @@ static int mjpeg_decode_scan_progressive_ac(MJpegDecodeContext *s, int ss, reference_data + block_offset, linesize, 8); } else { - s->dsp.idct_put(ptr, linesize, *block); + s->idsp.idct_put(ptr, linesize, *block); ptr += 8; } } @@ -1124,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; @@ -1206,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, @@ -1241,9 +1271,9 @@ static int mjpeg_decode_app(MJpegDecodeContext *s) av_log(s->avctx, AV_LOG_INFO, "Pegasus lossless jpeg header found\n"); skip_bits(&s->gb, 16); /* version ? */ - skip_bits(&s->gb, 16); /* unknwon always 0? */ - skip_bits(&s->gb, 16); /* unknwon always 0? */ - skip_bits(&s->gb, 16); /* unknwon always 0? */ + skip_bits(&s->gb, 16); /* unknown always 0? */ + skip_bits(&s->gb, 16); /* unknown always 0? */ + skip_bits(&s->gb, 16); /* unknown always 0? */ switch (get_bits(&s->gb, 8)) { case 1: s->rgb = 1; @@ -1297,30 +1327,31 @@ static int mjpeg_decode_com(MJpegDecodeContext *s) { int len = get_bits(&s->gb, 16); if (len >= 2 && 8 * len - 16 <= get_bits_left(&s->gb)) { + int i; char *cbuf = av_malloc(len - 1); - if (cbuf) { - int i; - for (i = 0; i < len - 2; i++) - cbuf[i] = get_bits(&s->gb, 8); - if (i > 0 && cbuf[i - 1] == '\n') - cbuf[i - 1] = 0; - else - cbuf[i] = 0; + if (!cbuf) + return AVERROR(ENOMEM); - if (s->avctx->debug & FF_DEBUG_PICT_INFO) - av_log(s->avctx, AV_LOG_INFO, "mjpeg comment: '%s'\n", cbuf); - - /* buggy avid, it puts EOI only at every 10th frame */ - if (!strcmp(cbuf, "AVID")) { - s->buggy_avid = 1; - } else if (!strcmp(cbuf, "CS=ITU601")) - s->cs_itu601 = 1; - else if ((len > 20 && !strncmp(cbuf, "Intel(R) JPEG Library", 21)) || - (len > 19 && !strncmp(cbuf, "Metasoft MJPEG Codec", 20))) - s->flipped = 1; - - av_free(cbuf); - } + for (i = 0; i < len - 2; i++) + cbuf[i] = get_bits(&s->gb, 8); + if (i > 0 && cbuf[i - 1] == '\n') + cbuf[i - 1] = 0; + else + cbuf[i] = 0; + + if (s->avctx->debug & FF_DEBUG_PICT_INFO) + av_log(s->avctx, AV_LOG_INFO, "mjpeg comment: '%s'\n", cbuf); + + /* buggy avid, it puts EOI only at every 10th frame */ + if (!strcmp(cbuf, "AVID")) { + s->buggy_avid = 1; + } else if (!strcmp(cbuf, "CS=ITU601")) + s->cs_itu601 = 1; + else if ((len > 20 && !strncmp(cbuf, "Intel(R) JPEG Library", 21)) || + (len > 19 && !strncmp(cbuf, "Metasoft MJPEG Codec", 20))) + s->flipped = 1; + + av_free(cbuf); } return 0; @@ -1351,7 +1382,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; } @@ -1392,7 +1423,7 @@ 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, - FF_INPUT_BUFFER_PADDING_SIZE); + AV_INPUT_BUFFER_PADDING_SIZE); av_log(s->avctx, AV_LOG_DEBUG, "escaping removed %td bytes\n", (buf_end - *buf_ptr) - (dst - s->buffer)); @@ -1435,7 +1466,7 @@ 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, - FF_INPUT_BUFFER_PADDING_SIZE); + AV_INPUT_BUFFER_PADDING_SIZE); } else { *unescaped_buf_ptr = *buf_ptr; *unescaped_buf_size = buf_end - *buf_ptr; @@ -1447,6 +1478,7 @@ int ff_mjpeg_find_marker(MJpegDecodeContext *s, 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; @@ -1467,154 +1499,170 @@ int ff_mjpeg_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, /* 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); + } - init_get_bits(&s->gb, unescaped_buf_ptr, unescaped_buf_size * 8); + av_log(avctx, AV_LOG_DEBUG, "marker=%x avail_size_in_buf=%td\n", + start_code, buf_end - buf_ptr); - s->start_code = start_code; - if (s->avctx->debug & FF_DEBUG_STARTCODE) - av_log(avctx, AV_LOG_DEBUG, "startcode: %X\n", start_code); + ret = init_get_bits(&s->gb, unescaped_buf_ptr, + unescaped_buf_size * 8); + if (ret < 0) + return ret; - /* 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); - } + s->start_code = start_code; + if (s->avctx->debug & FF_DEBUG_STARTCODE) + av_log(avctx, AV_LOG_DEBUG, "startcode: %X\n", start_code); - 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; + /* 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) { + ret = mjpeg_decode_com(s); + if (ret < 0) + return ret; + } + + 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 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; - } - if ((ret = av_frame_ref(data, s->picture_ptr)) < 0) - return ret; - *got_frame = 1; - - 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])); + 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; + } + 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; } + } + *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"); @@ -1634,7 +1682,10 @@ av_cold int ff_mjpeg_decode_end(AVCodecContext *avctx) MJpegDecodeContext *s = avctx->priv_data; int i, j; - if (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); @@ -1669,25 +1720,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, };