From d48132b7de7601c8c2769c0e92a43baa7759b991 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Fri, 20 Dec 2013 10:44:57 +0100 Subject: [PATCH] mjpegdec: apply flipping after decoding, not before This is simpler and removes a silly restriction on edges being present. --- libavcodec/mjpegdec.c | 32 +++++++++++++++++--------------- libavcodec/mjpegdec.h | 3 +++ 2 files changed, 20 insertions(+), 15 deletions(-) diff --git a/libavcodec/mjpegdec.c b/libavcodec/mjpegdec.c index 839d3c5..8210fd3 100644 --- a/libavcodec/mjpegdec.c +++ b/libavcodec/mjpegdec.c @@ -367,6 +367,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"); @@ -824,26 +830,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++) { @@ -1464,6 +1456,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; @@ -1585,8 +1578,17 @@ eoi_parser: if (s->bottom_field == !s->interlace_polarity) goto not_the_end; } - if ((ret = av_frame_ref(data, s->picture_ptr)) < 0) + 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; if (!s->lossless && diff --git a/libavcodec/mjpegdec.h b/libavcodec/mjpegdec.h index e3adc58..344d2cb 100644 --- a/libavcodec/mjpegdec.h +++ b/libavcodec/mjpegdec.h @@ -30,6 +30,7 @@ #define AVCODEC_MJPEGDEC_H #include "libavutil/log.h" +#include "libavutil/pixdesc.h" #include "avcodec.h" #include "get_bits.h" @@ -113,6 +114,8 @@ typedef struct MJpegDecodeContext { unsigned int ljpeg_buffer_size; int extern_huff; + + const AVPixFmtDescriptor *pix_desc; } MJpegDecodeContext; int ff_mjpeg_decode_init(AVCodecContext *avctx); -- 2.7.4