[FFmpeg-cvslog] avcodec/mjpegdec: Do not try to detect last scan but apply idct after all scans for progressive jpeg
Michael Niedermayer
git at videolan.org
Sun Jun 5 03:16:41 CEST 2016
ffmpeg | branch: release/3.0 | Michael Niedermayer <michael at niedermayer.cc> | Mon May 2 12:45:14 2016 +0200| [ef2b8416d95647c39634ddb2dcf2aa1bcbe9292a] | committer: Michael Niedermayer
avcodec/mjpegdec: Do not try to detect last scan but apply idct after all scans for progressive jpeg
Fixes: IMG-20160418-WA0002.jpg
Signed-off-by: Michael Niedermayer <michael at niedermayer.cc>
(cherry picked from commit deaf58abf236e09fc9b97db29f1edd064e4b5ad4)
Signed-off-by: Michael Niedermayer <michael at niedermayer.cc>
> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=ef2b8416d95647c39634ddb2dcf2aa1bcbe9292a
---
libavcodec/mjpegdec.c | 52 +++++++++++++++++++++++++++++++++++--------------
1 file changed, 37 insertions(+), 15 deletions(-)
diff --git a/libavcodec/mjpegdec.c b/libavcodec/mjpegdec.c
index bce5496..4bde42f 100644
--- a/libavcodec/mjpegdec.c
+++ b/libavcodec/mjpegdec.c
@@ -1369,11 +1369,7 @@ static int mjpeg_decode_scan_progressive_ac(MJpegDecodeContext *s, int ss,
int mb_x, mb_y;
int EOBRUN = 0;
int c = s->comp_index[0];
- uint8_t *data = s->picture_ptr->data[c];
- int linesize = s->linesize[c];
- int last_scan = 0;
int16_t *quant_matrix = s->quant_matrixes[s->quant_sindex[0]];
- int bytes_per_pixel = 1 + (s->bits > 8);
av_assert0(ss>=0 && Ah>=0 && Al>=0);
if (se < ss || se > 63) {
@@ -1384,15 +1380,10 @@ static int mjpeg_decode_scan_progressive_ac(MJpegDecodeContext *s, int ss,
// s->coefs_finished is a bitmask for coefficients coded
// ss and se are parameters telling start and end coefficients
s->coefs_finished[c] |= (2ULL << se) - (1ULL << ss);
- last_scan = !Al && !~s->coefs_finished[c];
-
- if (s->interlaced && s->bottom_field)
- data += linesize >> 1;
s->restart_count = 0;
for (mb_y = 0; mb_y < s->mb_height; mb_y++) {
- uint8_t *ptr = data + (mb_y * linesize * 8 >> s->avctx->lowres);
int block_idx = mb_y * s->block_stride[c];
int16_t (*block)[64] = &s->blocks[c][block_idx];
uint8_t *last_nnz = &s->last_nnz[c][block_idx];
@@ -1413,12 +1404,6 @@ static int mjpeg_decode_scan_progressive_ac(MJpegDecodeContext *s, int ss,
return AVERROR_INVALIDDATA;
}
- if (last_scan) {
- s->idsp.idct_put(ptr, linesize, *block);
- if (s->bits & 7)
- shift_output(s, ptr, linesize);
- ptr += bytes_per_pixel*8 >> s->avctx->lowres;
- }
if (handle_rstn(s, 0))
EOBRUN = 0;
}
@@ -1426,6 +1411,41 @@ static int mjpeg_decode_scan_progressive_ac(MJpegDecodeContext *s, int ss,
return 0;
}
+static void mjpeg_idct_scan_progressive_ac(MJpegDecodeContext *s)
+{
+ int mb_x, mb_y;
+ int c;
+ const int bytes_per_pixel = 1 + (s->bits > 8);
+ const int block_size = s->lossless ? 1 : 8;
+
+ for (c = 0; c < s->nb_components; c++) {
+ uint8_t *data = s->picture_ptr->data[c];
+ int linesize = s->linesize[c];
+ int h = s->h_max / s->h_count[c];
+ int v = s->v_max / s->v_count[c];
+ int mb_width = (s->width + h * block_size - 1) / (h * block_size);
+ int mb_height = (s->height + v * block_size - 1) / (v * block_size);
+
+ if (~s->coefs_finished[c])
+ av_log(s->avctx, AV_LOG_WARNING, "component %d is incomplete\n", c);
+
+ if (s->interlaced && s->bottom_field)
+ data += linesize >> 1;
+
+ for (mb_y = 0; mb_y < mb_height; mb_y++) {
+ uint8_t *ptr = data + (mb_y * linesize * 8 >> s->avctx->lowres);
+ int block_idx = mb_y * s->block_stride[c];
+ int16_t (*block)[64] = &s->blocks[c][block_idx];
+ for (mb_x = 0; mb_x < mb_width; mb_x++, block++) {
+ s->idsp.idct_put(ptr, linesize, *block);
+ if (s->bits & 7)
+ shift_output(s, ptr, linesize);
+ ptr += bytes_per_pixel*8 >> s->avctx->lowres;
+ }
+ }
+ }
+}
+
int ff_mjpeg_decode_sos(MJpegDecodeContext *s, const uint8_t *mb_bitmask,
int mb_bitmask_size, const AVFrame *reference)
{
@@ -2162,6 +2182,8 @@ int ff_mjpeg_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
break;
case EOI:
eoi_parser:
+ if (avctx->skip_frame != AVDISCARD_ALL && s->progressive && s->cur_scan && s->got_picture)
+ mjpeg_idct_scan_progressive_ac(s);
s->cur_scan = 0;
if (!s->got_picture) {
av_log(avctx, AV_LOG_WARNING,
More information about the ffmpeg-cvslog
mailing list