X-Git-Url: https://git.ao2.it/libam7xxx.git/blobdiff_plain/ca8e35d5dcc10f8f00e4852d2e02390e9c338265..a257bc45edccc9844b78e0a84d956976ab5a203e:/examples/am7xxx-play.c?ds=sidebyside diff --git a/examples/am7xxx-play.c b/examples/am7xxx-play.c index 4987c62..81aff84 100644 --- a/examples/am7xxx-play.c +++ b/examples/am7xxx-play.c @@ -211,6 +211,7 @@ static int video_output_init(struct video_output_ctx *output_ctx, goto out; } + /* YUVJ420P is deprecated in swscaler, but mjpeg still relies on it. */ output_codec_ctx->pix_fmt = AV_PIX_FMT_YUVJ420P; output_codec_ctx->codec_id = AV_CODEC_ID_MJPEG; output_codec_ctx->codec_type = AVMEDIA_TYPE_VIDEO; @@ -256,6 +257,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 +431,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; @@ -378,7 +440,7 @@ static int am7xxx_play(const char *input_format_string, /* if we got the complete frame */ if (got_frame) { - /* + /* * Rescaling the frame also changes its pixel format * to the raw format supported by the projector if * this was set in video_output_init() @@ -400,10 +462,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;