Jeff Downs <[EMAIL PROTECTED]> added the comment:

See attached which removes first long ref that can be found when this illegal
case is encountered.

I'm not crazy about the pointers to mmco fields, but that was the best way I
could think of w/out duplicating the field cases and w/out making an otherwise
useless function.

----------
nosy: +heydowns
status: new -> open
substatus: new -> analyzed

______________________________________________________
FFmpeg issue tracker <[EMAIL PROTECTED]>
<https://roundup.mplayerhq.hu/roundup/ffmpeg/issue281>
______________________________________________________
Index: libavcodec/h264.c
===================================================================
--- libavcodec/h264.c	(revision 11162)
+++ libavcodec/h264.c	(working copy)
@@ -3664,13 +3664,37 @@
 
             if(h->long_ref_count + h->short_ref_count == h->sps.ref_frame_count &&
                     !(FIELD_PICTURE && !s->first_field && s->current_picture_ptr->reference)) {
+                int *pic_num_field1, *pic_num_field2;
+
+                if (h->short_ref_count) {    
                 h->mmco[0].opcode= MMCO_SHORT2UNUSED;
                 h->mmco[0].short_pic_num= h->short_ref[ h->short_ref_count - 1 ]->frame_num;
                 h->mmco_index= 1;
+                    pic_num_field1= &h->mmco[0].short_pic_num;
+                    pic_num_field2= &h->mmco[1].short_pic_num;
+                } else {
+                    /* Only long refs.
+                     * Spec says there has to be at least one short term ref
+                     * when sliding window is full. File is corrupt.
+                     * Clean out an arbitrary long ref to make room for
+                     * the new reference frame.
+                     */
+                    for (i = 0; i < 16; ++i)
+                        if (h->long_ref[i])
+                            break;
+
+                    assert(i < 16);
+                    h->mmco[0].opcode= MMCO_LONG2UNUSED;
+                    h->mmco[0].long_arg= i;
+                    h->mmco_index= 1;
+                    pic_num_field1= &h->mmco[0].long_arg;
+                    pic_num_field2= &h->mmco[1].long_arg;
+                }
                 if (FIELD_PICTURE) {
-                    h->mmco[0].short_pic_num *= 2;
-                    h->mmco[1].opcode= MMCO_SHORT2UNUSED;
-                    h->mmco[1].short_pic_num= h->mmco[0].short_pic_num + 1;
+                    /* Put MMCO ops in terms of fields */
+                    *pic_num_field1 *= 2;
+                    *pic_num_field2= *pic_num_field1 + 1;
+                    h->mmco[1].opcode= h->mmco[0].opcode;
                     h->mmco_index= 2;
                 }
             }else

Reply via email to