On Wed, Mar 29, 2017 at 3:37 PM, wm4 <nfx...@googlemail.com> wrote:

> On Wed, 29 Mar 2017 15:03:55 +0200
> Matthieu Bouron <matthieu.bou...@gmail.com> wrote:
>
> > ---
> >  doc/examples/filtering_video.c | 32 ++++++++++++++++++++++++++------
> >  1 file changed, 26 insertions(+), 6 deletions(-)
> >
> > diff --git a/doc/examples/filtering_video.c b/doc/examples/filtering_
> video.c
> > index 15116d3881..b664c69f9d 100644
> > --- a/doc/examples/filtering_video.c
> > +++ b/doc/examples/filtering_video.c
> > @@ -211,6 +211,7 @@ int main(int argc, char **argv)
> >  {
> >      int ret;
> >      AVPacket packet;
> > +    int keep_packet = 0;
> >      AVFrame *frame = av_frame_alloc();
> >      AVFrame *filt_frame = av_frame_alloc();
> >      int got_frame;
> > @@ -234,14 +235,30 @@ int main(int argc, char **argv)
> >
> >      /* read all packets */
> >      while (1) {
> > -        if ((ret = av_read_frame(fmt_ctx, &packet)) < 0)
> > -            break;
> > +        if (!keep_packet) {
> > +            if ((ret = av_read_frame(fmt_ctx, &packet)) < 0)
> > +                break;
> > +            keep_packet = 1;
> > +        }
> >
> >          if (packet.stream_index == video_stream_index) {
> >              got_frame = 0;
> > -            ret = avcodec_decode_video2(dec_ctx, frame, &got_frame,
> &packet);
> > -            if (ret < 0) {
> > -                av_log(NULL, AV_LOG_ERROR, "Error decoding video\n");
> > +
> > +            ret = avcodec_send_packet(dec_ctx, &packet);
> > +            if (ret >= 0) {
> > +                keep_packet = 0;
> > +            } else if (ret != AVERROR(EAGAIN) && ret != AVERROR_EOF) {
>
> If you have packets after the decoder entered the EOF state, you
> probably want to discard them. Either that, or reset the decoder after
> it's flushed and start over. Anyway, normally this shouldn't happen.
>
> You could also avoid the keep_packet business by running receive_frame
> in a loop after send_packet (then send_packet can never fail with
> EAGAIN).
>
> > +                av_log(NULL, AV_LOG_ERROR, "Error while sending a
> packet to the decoder\n");
> > +                break;
> > +            }
> > +
> > +            ret = avcodec_receive_frame(dec_ctx, frame);
> > +            if (ret >= 0) {
> > +                got_frame = 1;
> > +            } else if (ret == AVERROR_EOF) {
> > +                break;
> > +            } else if (ret != AVERROR(EAGAIN)) {
> > +                av_log(NULL, AV_LOG_ERROR, "Error while receiving a
> frame from the decoder\n");
> >                  break;
> >              }
> >
> > @@ -266,8 +283,11 @@ int main(int argc, char **argv)
> >                  }
> >                  av_frame_unref(frame);
> >              }
> > +        } else {
> > +            keep_packet = 0;
> >          }
> > -        av_packet_unref(&packet);
> > +        if (!keep_packet)
> > +           av_packet_unref(&packet);
> >      }
> >  end:
> >      avfilter_graph_free(&filter_graph);
>
> Otherwise should work.
>

New patch attached (removing the keep_packet logic).
From e9e5b3e679a12fdd9495c53177ade51c3dee7ba2 Mon Sep 17 00:00:00 2001
From: Matthieu Bouron <matthieu.bou...@gmail.com>
Date: Wed, 29 Mar 2017 14:58:01 +0200
Subject: [PATCH] doc/examples/filtering_video: switch to new decoding API

---
 doc/examples/filtering_video.c | 46 +++++++++++++++++++++++++-----------------
 1 file changed, 27 insertions(+), 19 deletions(-)

diff --git a/doc/examples/filtering_video.c b/doc/examples/filtering_video.c
index 15116d3881..4d973024f1 100644
--- a/doc/examples/filtering_video.c
+++ b/doc/examples/filtering_video.c
@@ -213,7 +213,6 @@ int main(int argc, char **argv)
     AVPacket packet;
     AVFrame *frame = av_frame_alloc();
     AVFrame *filt_frame = av_frame_alloc();
-    int got_frame;
 
     if (!frame || !filt_frame) {
         perror("Could not allocate frame");
@@ -238,33 +237,42 @@ int main(int argc, char **argv)
             break;
 
         if (packet.stream_index == video_stream_index) {
-            got_frame = 0;
-            ret = avcodec_decode_video2(dec_ctx, frame, &got_frame, &packet);
+            ret = avcodec_send_packet(dec_ctx, &packet);
             if (ret < 0) {
-                av_log(NULL, AV_LOG_ERROR, "Error decoding video\n");
+                av_log(NULL, AV_LOG_ERROR, "Error while sending a packet to the decoder\n");
                 break;
             }
 
-            if (got_frame) {
-                frame->pts = av_frame_get_best_effort_timestamp(frame);
-
-                /* push the decoded frame into the filtergraph */
-                if (av_buffersrc_add_frame_flags(buffersrc_ctx, frame, AV_BUFFERSRC_FLAG_KEEP_REF) < 0) {
-                    av_log(NULL, AV_LOG_ERROR, "Error while feeding the filtergraph\n");
+            while (ret >= 0) {
+                ret = avcodec_receive_frame(dec_ctx, frame);
+                if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
                     break;
+                } else if (ret < 0) {
+                    av_log(NULL, AV_LOG_ERROR, "Error while receiving a frame from the decoder\n");
+                    goto end;
                 }
 
-                /* pull filtered frames from the filtergraph */
-                while (1) {
-                    ret = av_buffersink_get_frame(buffersink_ctx, filt_frame);
-                    if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
+                if (ret >= 0) {
+                    frame->pts = av_frame_get_best_effort_timestamp(frame);
+
+                    /* push the decoded frame into the filtergraph */
+                    if (av_buffersrc_add_frame_flags(buffersrc_ctx, frame, AV_BUFFERSRC_FLAG_KEEP_REF) < 0) {
+                        av_log(NULL, AV_LOG_ERROR, "Error while feeding the filtergraph\n");
                         break;
-                    if (ret < 0)
-                        goto end;
-                    display_frame(filt_frame, buffersink_ctx->inputs[0]->time_base);
-                    av_frame_unref(filt_frame);
+                    }
+
+                    /* pull filtered frames from the filtergraph */
+                    while (1) {
+                        ret = av_buffersink_get_frame(buffersink_ctx, filt_frame);
+                        if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
+                            break;
+                        if (ret < 0)
+                            goto end;
+                        display_frame(filt_frame, buffersink_ctx->inputs[0]->time_base);
+                        av_frame_unref(filt_frame);
+                    }
+                    av_frame_unref(frame);
                 }
-                av_frame_unref(frame);
             }
         }
         av_packet_unref(&packet);
-- 
2.12.0

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

Reply via email to