aboutsummaryrefslogtreecommitdiffstats
path: root/libavcodec
diff options
context:
space:
mode:
authorMichael Niedermayer <michael@niedermayer.cc>2016-05-02 12:45:14 +0200
committerMichael Niedermayer <michael@niedermayer.cc>2016-05-02 23:59:14 +0200
commit342b6d371895cd036a626d6dc8cf17650e8ffc0a (patch)
tree7ac24b39511a8acf2efd61b550ba645e5342a65a /libavcodec
parent74b8c4a60bb9af340773b82b7c64833af15ae612 (diff)
downloadffmpeg-342b6d371895cd036a626d6dc8cf17650e8ffc0a.tar.gz
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@niedermayer.cc> (cherry picked from commit deaf58abf236e09fc9b97db29f1edd064e4b5ad4) Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
Diffstat (limited to 'libavcodec')
-rw-r--r--libavcodec/mjpegdec.c52
1 files changed, 37 insertions, 15 deletions
diff --git a/libavcodec/mjpegdec.c b/libavcodec/mjpegdec.c
index 22a852d4a5..d69474f439 100644
--- a/libavcodec/mjpegdec.c
+++ b/libavcodec/mjpegdec.c
@@ -1342,11 +1342,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) {
@@ -1357,15 +1353,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];
@@ -1386,12 +1377,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;
}
@@ -1399,6 +1384,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)
{
@@ -2081,6 +2101,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,