On Wed, Oct 28, 2015 at 02:57:14AM +0100, Michael Niedermayer wrote:
> On Tue, Oct 27, 2015 at 11:15:29PM +0100, Matthieu Bouron wrote:
> > On Sun, Oct 18, 2015 at 11:06:50AM +0200, Matthieu Bouron wrote:
> > [...]
> > > 
> > > Patch updated, the markers are now properly skipped (which also fixes a
> > > crash).
> > 
> > Patch updated. It fixes an issue with mjpeg streams (and in particular with
> > the fate sample ffmpeg-issue-897.avi) due to the EOI marker not handled when
> > skip_frame is set to AVDISCARD_ALL.
> > 
> > Matthieu
> 
> >  mjpegdec.c |   26 ++++++++++++++++++++++++++
> >  1 file changed, 26 insertions(+)
> > 36d41f1bded2f864394843c6a49d8cc24933688c  
> > 0002-lavc-mjpegdec-honor-skip_frame-option.patch
> > From 7325810d812c4182cd42946687a1f4abc04999d1 Mon Sep 17 00:00:00 2001
> > From: Matthieu Bouron <matthieu.bou...@stupeflix.com>
> > Date: Fri, 9 Oct 2015 15:15:15 +0200
> > Subject: [PATCH 2/3] lavc/mjpegdec: honor skip_frame option
> > 
> > ---
> >  libavcodec/mjpegdec.c | 26 ++++++++++++++++++++++++++
> >  1 file changed, 26 insertions(+)
> > 
> > diff --git a/libavcodec/mjpegdec.c b/libavcodec/mjpegdec.c
> > index 1a86b7b..b4ff83c 100644
> > --- a/libavcodec/mjpegdec.c
> > +++ b/libavcodec/mjpegdec.c
> > @@ -2038,6 +2038,22 @@ int ff_mjpeg_decode_frame(AVCodecContext *avctx, 
> > void *data, int *got_frame,
> >              return AVERROR(ENOSYS);
> >          }
> >  
> > +        if (avctx->skip_frame == AVDISCARD_ALL) {
> > +            int i, found = 0;
> > +            static const int start_codes[] = { SOF0,
> > +                SOF1, SOF2, SOF3, SOF48, SOI, EOI };
> > +
> > +            for (i = 0; i < FF_ARRAY_ELEMS(start_codes); i++) {
> > +                if (start_code == start_codes[i]) {
> > +                    found = 1;
> > +                    break;
> > +                }
> > +            }
> > +            if (!found) {
> > +                goto skip;
> > +            }
> > +        }
> > +
> >          switch (start_code) {
> >          case SOI:
> >              s->restart_interval = 0;
> > @@ -2103,6 +2119,10 @@ eoi_parser:
> >                  if (s->bottom_field == !s->interlace_polarity)
> >                      break;
> >              }
> > +            if (avctx->skip_frame == AVDISCARD_ALL) {
> > +                s->got_picture = 0;
> 
> > +                goto the_end;
> 
> this would jump to all kinds of post scale and convert code
> that should probably be skiped over just to be sure it doesnt run
> otherwise patch LGTM and seems not breaking anything i tested
>

Patch updated, the post processing part is now skipped. The SOS marker is
now handled properly so the scan counter is incremented.
The decoder will also still error out if there is a SOF marker but no SOS
markers.

Thanks for all the feedback.

Matthieu
>From 46a8815eb5764e1212e3b6b329fba9dfbeb9c352 Mon Sep 17 00:00:00 2001
From: Matthieu Bouron <matthieu.bou...@stupeflix.com>
Date: Fri, 9 Oct 2015 15:15:15 +0200
Subject: [PATCH 2/3] lavc/mjpegdec: honor skip_frame option

---
 libavcodec/mjpegdec.c | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/libavcodec/mjpegdec.c b/libavcodec/mjpegdec.c
index 1a86b7b..96a2b4a 100644
--- a/libavcodec/mjpegdec.c
+++ b/libavcodec/mjpegdec.c
@@ -2038,6 +2038,22 @@ int ff_mjpeg_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
             return AVERROR(ENOSYS);
         }
 
+        if (avctx->skip_frame == AVDISCARD_ALL) {
+            int i, found = 0;
+            static const int start_codes[] = { SOF0,
+                SOF1, SOF2, SOF3, SOF48, SOI, SOS, EOI };
+
+            for (i = 0; i < FF_ARRAY_ELEMS(start_codes); i++) {
+                if (start_code == start_codes[i]) {
+                    found = 1;
+                    break;
+                }
+            }
+            if (!found) {
+                goto skip;
+            }
+        }
+
         switch (start_code) {
         case SOI:
             s->restart_interval = 0;
@@ -2103,6 +2119,10 @@ eoi_parser:
                 if (s->bottom_field == !s->interlace_polarity)
                     break;
             }
+            if (avctx->skip_frame == AVDISCARD_ALL) {
+                s->got_picture = 0;
+                goto the_end_no_picture;
+            }
             if ((ret = av_frame_ref(frame, s->picture_ptr)) < 0)
                 return ret;
             *got_frame = 1;
@@ -2126,6 +2146,9 @@ eoi_parser:
             goto the_end;
         case SOS:
             s->cur_scan++;
+            if (avctx->skip_frame == AVDISCARD_ALL)
+                break;
+
             if ((ret = ff_mjpeg_decode_sos(s, NULL, 0, NULL)) < 0 &&
                 (avctx->err_recognition & AV_EF_EXPLODE))
                 goto fail;
@@ -2148,6 +2171,7 @@ eoi_parser:
             break;
         }
 
+skip:
         /* eof process start code */
         buf_ptr += (get_bits_count(&s->gb) + 7) / 8;
         av_log(avctx, AV_LOG_DEBUG,
@@ -2158,6 +2182,7 @@ eoi_parser:
         av_log(avctx, AV_LOG_WARNING, "EOI missing, emulating\n");
         goto eoi_parser;
     }
+
     av_log(avctx, AV_LOG_FATAL, "No JPEG data found in image\n");
     return AVERROR_INVALIDDATA;
 fail:
@@ -2344,6 +2369,7 @@ the_end:
     av_dict_copy(avpriv_frame_get_metadatap(data), s->exif_metadata, 0);
     av_dict_free(&s->exif_metadata);
 
+the_end_no_picture:
     av_log(avctx, AV_LOG_DEBUG, "decode frame unused %"PTRDIFF_SPECIFIER" bytes\n",
            buf_end - buf_ptr);
 //  return buf_end - buf_ptr;
-- 
2.6.2

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel

Reply via email to