am7xxx-play: stop using avcodec_decode_video2() and avcodec_encode_video2()
authorAntonio Ospite <ao2@ao2.it>
Wed, 28 Feb 2018 15:23:34 +0000 (16:23 +0100)
committerAntonio Ospite <ao2@ao2.it>
Thu, 1 Mar 2018 15:12:16 +0000 (16:12 +0100)
Since FFMpeg 3.1, avcodec_decode_video2() and avcodec_encode_video2()
have been deprecated in favor of the more generic send/receive API.

Provide some wrappers to ease the transition between the two APIs.

The change fixes the following warnings:

  .../libam7xxx/examples/am7xxx-play.c: In function ‘am7xxx_play’:
  .../libam7xxx/examples/am7xxx-play.c:372:3: warning: ‘avcodec_decode_video2’ is deprecated [-Wdeprecated-declarations]
     ret = avcodec_decode_video2(input_ctx.codec_ctx, frame_raw, &got_frame, &in_packet);
     ^~~
  In file included from /usr/include/x86_64-linux-gnu/libavformat/avformat.h:319:0,
                   from /usr/include/x86_64-linux-gnu/libavdevice/avdevice.h:51,
                   from .../libam7xxx/examples/am7xxx-play.c:32:
  /usr/include/x86_64-linux-gnu/libavcodec/avcodec.h:4993:5: note: declared here
   int avcodec_decode_video2(AVCodecContext *avctx, AVFrame *picture,
       ^~~~~~~~~~~~~~~~~~~~~
  .../libam7xxx/examples/am7xxx-play.c:403:5: warning: ‘avcodec_encode_video2’ is deprecated [-Wdeprecated-declarations]
       ret = avcodec_encode_video2(output_ctx.codec_ctx,
       ^~~
  In file included from /usr/include/x86_64-linux-gnu/libavformat/avformat.h:319:0,
                   from /usr/include/x86_64-linux-gnu/libavdevice/avdevice.h:51,
                   from .../libam7xxx/examples/am7xxx-play.c:32:
  /usr/include/x86_64-linux-gnu/libavcodec/avcodec.h:5508:5: note: declared here
   int avcodec_encode_video2(AVCodecContext *avctx, AVPacket *avpkt,
       ^~~~~~~~~~~~~~~~~~~~~

examples/am7xxx-play.c

index 4987c62..e3ceb5c 100644 (file)
@@ -256,6 +256,67 @@ out:
 }
 
 
+/*
+ * Wrap the new avcodec API from FFMpeg 3.1 to minimize the changes in the
+ * user code.
+ *
+ * If the use of the wrappers were to be made conditional, a check like the
+ * following could be used:
+ *
+ *     #if (LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 48, 101))
+ *
+ * As derived from the APIchanges document:
+ * https://github.com/FFmpeg/FFmpeg/blob/master/doc/APIchanges
+ *
+ * The wrapper implementation has been taken from:
+ * https://blogs.gentoo.org/lu_zero/2016/03/29/new-avcodec-api/
+ */
+static int decode(AVCodecContext *avctx, AVFrame *frame, int *got_frame, AVPacket *pkt)
+{
+       int ret;
+
+       *got_frame = 0;
+
+       if (pkt) {
+               ret = avcodec_send_packet(avctx, pkt);
+               /*
+                * In particular, we don't expect AVERROR(EAGAIN), because we
+                * read all decoded frames with avcodec_receive_frame() until
+                * done.
+                */
+               if (ret < 0)
+                       return ret == AVERROR_EOF ? 0 : ret;
+       }
+
+       ret = avcodec_receive_frame(avctx, frame);
+       if (ret < 0 && ret != AVERROR(EAGAIN) && ret != AVERROR_EOF)
+               return ret;
+       if (ret >= 0)
+               *got_frame = 1;
+
+       return 0;
+}
+
+static int encode(AVCodecContext *avctx, AVPacket *pkt, int *got_packet, AVFrame *frame)
+{
+       int ret;
+
+       *got_packet = 0;
+
+       ret = avcodec_send_frame(avctx, frame);
+       if (ret < 0)
+               return ret;
+
+       ret = avcodec_receive_packet(avctx, pkt);
+       if (!ret)
+               *got_packet = 1;
+       if (ret == AVERROR(EAGAIN))
+               return 0;
+
+       return ret;
+}
+
+
 static int am7xxx_play(const char *input_format_string,
                       AVDictionary **input_options,
                       const char *input_path,
@@ -369,7 +430,7 @@ static int am7xxx_play(const char *input_format_string,
 
                /* decode */
                got_frame = 0;
-               ret = avcodec_decode_video2(input_ctx.codec_ctx, frame_raw, &got_frame, &in_packet);
+               ret = decode(input_ctx.codec_ctx, frame_raw, &got_frame, &in_packet);
                if (ret < 0) {
                        fprintf(stderr, "cannot decode video\n");
                        run = 0;
@@ -400,10 +461,10 @@ static int am7xxx_play(const char *input_format_string,
                                out_packet.data = NULL;
                                out_packet.size = 0;
                                got_packet = 0;
-                               ret = avcodec_encode_video2(output_ctx.codec_ctx,
-                                                           &out_packet,
-                                                           frame_scaled,
-                                                           &got_packet);
+                               ret = encode(output_ctx.codec_ctx,
+                                            &out_packet,
+                                            &got_packet,
+                                            frame_scaled);
                                if (ret < 0 || !got_packet) {
                                        fprintf(stderr, "cannot encode video\n");
                                        run = 0;