Index: libavcodec/mjpeg.c =================================================================== --- libavcodec/mjpeg.c (revision 6260) +++ libavcodec/mjpeg.c (working copy) @@ -1182,6 +1182,10 @@ s->qscale_table= av_mallocz((s->width+15)/16); s->first_picture = 0; + + s->avctx->vis_x0=s->avctx->vis_y1=0; + s->avctx->vis_x1=width; + s->avctx->vis_y1=height; } if(s->interlaced && s->bottom_field) @@ -1465,21 +1469,29 @@ static int mjpeg_decode_scan(MJpegDecodeContext *s){ int i, mb_x, mb_y; const int nb_components=3; + int shft = 3 - s->avctx->lowres; + int x0 = s->avctx->vis_x0 >> shft, x1 = s->avctx->vis_x1+(1<<3-s->avctx->lowres)-1 >> shft; + int y0 = s->avctx->vis_y0 >> shft, y1 = s->avctx->vis_y1+(1<<3-s->avctx->lowres)-1 >> shft; + int px, py; - for(mb_y = 0; mb_y < s->mb_height; mb_y++) { + if (s->avctx->vis_x1<=s->avctx->vis_x0 || s->avctx->vis_y1<=s->avctx->vis_y0) return 0; + for(py = 0, mb_y = 0; mb_y < s->mb_height && py < y1; mb_y++, py += s->v_max) { for(mb_x = 0; mb_x < s->mb_width; mb_x++) { if (s->restart_interval && !s->restart_count) s->restart_count = s->restart_interval; for(i=0;inb_blocks[i]; c = s->comp_index[i]; h = s->h_scount[i]; v = s->v_scount[i]; x = 0; - y = 0; + ptr = s->picture.data[c] + ((s->linesize[c] * (v * mb_y) + h * mb_x) << 3 - s->avctx->lowres); + px = mb_x*s->h_max; + if (s->interlaced && s->bottom_field) + ptr += s->linesize[c] >> 1; for(j=0;jblock, 0, sizeof(s->block)); if (decode_block(s, s->block, i, @@ -1488,19 +1500,18 @@ dprintf("error y=%d x=%d\n", mb_y, mb_x); return -1; } -// dprintf("mb: %d %d processed\n", mb_y, mb_x); - ptr = s->picture.data[c] + - (((s->linesize[c] * (v * mb_y + y) * 8) + - (h * mb_x + x) * 8) >> s->avctx->lowres); - if (s->interlaced && s->bottom_field) - ptr += s->linesize[c] >> 1; -//av_log(NULL, AV_LOG_DEBUG, "%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); - s->idct_put(ptr, s->linesize[c], s->block); + if (px*h+s->v_max > x0*h && px < x1 && py*v+s->v_max > y0*v) + s->idct_put(ptr, s->linesize[c], s->block); + ptr += 1 << shft; + px++; if (++x == h) { x = 0; - y++; + px-=h; + py++; + ptr += s->linesize[c] - h << shft; } } + py-=v; } /* (< 1350) buggy workaround for Spectralfan.mov, should be fixed */ if (s->restart_interval && (s->restart_interval < 1350) && Index: libavcodec/utils.c =================================================================== --- libavcodec/utils.c (revision 6260) +++ libavcodec/utils.c (working copy) @@ -784,6 +784,9 @@ s->palctrl = NULL; s->reget_buffer= avcodec_default_reget_buffer; + + s->vis_x0=s->vis_y0=0; + s->vis_x1=s->vis_y1=INT_MAX; } /** Index: libavcodec/avcodec.h =================================================================== --- libavcodec/avcodec.h (revision 6260) +++ libavcodec/avcodec.h (working copy) @@ -1776,6 +1776,13 @@ int lowres; /** + * Partial decoding. Visible rectangle: x0 <= x < x1 + * - encoding: unused + * - decoding: set by user, defaults by avcodec_alloc_context, reset by codec if sizes was changed + */ + int vis_x0, vis_x1, vis_y0, vis_y1; + + /** * bitsream width / height. may be different from width/height if lowres * or other things are used * - encoding: unused