Jeff Downs <[email protected]> added the comment:

On Sun, 2 Aug 2009, Michael Niedermayer wrote:

> On Wed, Jul 29, 2009 at 09:25:56PM +0000, Jeff Downs wrote:
> 
> there are so any mb_y checks, why dont you fix one of them instead of adding
> yet another.
> slice_decode_thread contains a check it can be moved up

Not sure what you mean by moving this one up. slice_decode_thread is 
re-reading from the input bitstream, so it needs to re-check the input 
and also know when its reached the slice to stop reading. 
... unless we want to get in to bounding the threaded reading code to 
checked input data rather than bounding by start code/mb_y ranges.

> decode_chunks contains one limited to mpeg2

That one implements -skip_bottom.  Currently we emit warnings for bad 
slice numbers, but we wouldn't want to emit warnings for skipped mb rows.

Attached moves the mb_y check (which emits the warning) in decode_slice up 
to decode_chunk.  For non-threaded decoding, behavior will be the same. 
For threaded decoding, it fixes the original issue, makes certain the 
thread context's end_mb_y is valid, and also fixes the thread context 
allocation for field pictures. One less check is performed at threaded 
decoding time, at the expense of the extra check at thread allocation 
time.

Also noticed that the skip_bottom code is wrong for field pics, but that's 
a separate issue.

_____________________________________________________
FFmpeg issue tracker <[email protected]>
<https://roundup.ffmpeg.org/roundup/ffmpeg/issue1277>
_____________________________________________________
Index: libavcodec/mpeg12.c
===================================================================
--- libavcodec/mpeg12.c (revision 19605)
+++ libavcodec/mpeg12.c (working copy)
@@ -1690,11 +1690,6 @@
     s->resync_mb_x=
     s->resync_mb_y= -1;
 
-    if (mb_y<<field_pic >= s->mb_height){
-        av_log(s->avctx, AV_LOG_ERROR, "slice below image (%d >= %d)\n", mb_y, 
s->mb_height);
-        return -1;
-    }
-
     init_get_bits(&s->gb, *buf, buf_size*8);
 
     ff_mpeg1_clean_buffers(s);
@@ -2362,6 +2357,8 @@
             if (start_code >= SLICE_MIN_START_CODE &&
                 start_code <= SLICE_MAX_START_CODE) {
                 int mb_y= start_code - SLICE_MIN_START_CODE;
+                int mb_h= s2->mb_height >>
+                          (s2->picture_structure != PICT_FRAME);
 
                 if(s2->last_picture_ptr==NULL){
                 /* Skip B-frames if we do not have reference frames and gop is 
not closed */
@@ -2396,6 +2393,11 @@
                         break;
                 }
 
+                if (mb_y >= mb_h){
+                    av_log(avctx, AV_LOG_ERROR, "slice below image (%d >= 
%d)\n", mb_y, mb_h);
+                    break;
+                }
+
                 if(!s2->pict_type){
                     av_log(avctx, AV_LOG_ERROR, "Missing picture start 
code\n");
                     break;
@@ -2417,12 +2419,12 @@
                 }
 
                 if(avctx->thread_count > 1){
-                    int threshold= (s2->mb_height*s->slice_count + 
avctx->thread_count/2) / avctx->thread_count;
+                    int threshold= (mb_h*s->slice_count + 
avctx->thread_count/2) / avctx->thread_count;
                     if(threshold <= mb_y){
                         MpegEncContext *thread_context= 
s2->thread_context[s->slice_count];
 
                         thread_context->start_mb_y= mb_y;
-                        thread_context->end_mb_y  = s2->mb_height;
+                        thread_context->end_mb_y  = mb_h;
                         if(s->slice_count){
                             s2->thread_context[s->slice_count-1]->end_mb_y= 
mb_y;
                             ff_update_duplicate_context(thread_context, s2);

Reply via email to